2012-06-10 18 views
16
[[email protected] python]$ cat hello_world.cc 
#include <string> 
#include <Python.h> 
#include <boost/python.hpp> 

namespace { 
    std::string greet() { return "Helloworld"; } 
} 

using namespace boost::python; 

BOOST_PYTHON_MODULE(hello_world) 
{ 
    def("greet",greet); 
} 

[[email protected] python]$ g++ -c -fPIC hello_world.cc -I/path/to/boost/headers -I/path/to/python/headers -o hello_world.o 
[[email protected] python]$ g++ -shared -Wl,-soname,libhello_world.so -o libhello_world.so hello_world.o 
[[email protected] python]$ python 
Python 2.7.1 (r271:86832, Jan 10 2011, 09:46:57) 
[GCC 3.4.5 20051201 (Red Hat 3.4.5-2)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import sys 
>>> sys.path.append('.') 
>>> import hello_world 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ImportError: No module named hello_world 
>>> 

Creé el archivo .so como se muestra arriba, pero no puedo importar dentro de python. ¿Qué me estoy perdiendo?Cómo importar el módulo python desde el archivo .so?

Respuesta

8

Debe llamarse hello_world.so, no libhello_world.so.

+2

gracias. Ahora obtengo 'ImportError: ./hello_world.so: undefined symbol: _ZNK12boost_1_47_06python7objects21py_function_impl_base9max_arityEv' – balki

+1

@balki: No estableciste un enlace con Boost.Python. –

+0

Me vinculé contra boost_python, ahora obtengo 'ImportError: libboost_python: no se puede abrir el archivo de objeto compartido: No existe dicho archivo o directorio'. Si exporto 'LD_LIBRARY_PATH =/path/to/boost_python_lib', funciona bien. ¿Cómo especifico en cmdline? – balki

13

toma ese archivo 'hello_world.so' y crea un nuevo archivo python (en el mismo directorio) llamado 'hello_world.py'. Ponga el código a continuación en él ...

def __bootstrap__(): 
    global __bootstrap__, __loader__, __file__ 
    import sys, pkg_resources, imp 
    __file__ = pkg_resources.resource_filename(__name__,'hello_world.so') 
    __loader__ = None; del __bootstrap__, __loader__ 
    imp.load_dynamic(__name__,__file__) 
__bootstrap__() 

Ahora puede importar este hola_mundo como:

>>> import hello_world 
+2

¿Debería cambiarse el nombre de "\ __ bootstrap__" a, decir "\ _bootstrap"? Pasé mucho tiempo tratando de encontrar la documentación, pensando que era una palabra reservada especial, pero no pude encontrar nada. Desde https://www.python.org/dev/peps/pep-0008/#naming-conventions: \ __ double_leading_and_trailing_underscore__: objetos o atributos "mágicos" que viven en espacios de nombres controlados por el usuario. P.ej. \ __ init__, \ __ file__ o \ __ file__. Nunca inventes tales nombres; solo utilícelos según lo documentado. –

+0

podemos copiar pero podemos agregar algunos detalles sobre la información. Cómo funciona. – user765443

+0

Intenté esto con readline del módulo. Tengo una versión de python n. ° 1 (2.7.12) instalada con apt-get, que tiene readline, y otra versión n. ° 2 (2.7.11), simplemente expandida, que no funciona. Así que agregué un readline.py en uno de los directorios en sys.path para la versión # 2, y un enlace simbólico en el mismo directorio a /usr/lib/python2.7/lib-dynload/readline.x86_64-linux-gnu. entonces desde la versión # 1. Aún tengo el error. –

Cuestiones relacionadas