2012-06-10 16 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 
>>> 

Ho creato il file .so come mostrato sopra ma non riesco ad importarlo all'interno di python. cosa mi sto perdendo?Come importare il modulo python dal file .so?

risposta

8

Deve essere chiamato hello_world.so, non libhello_world.so.

+2

grazie. Ora ho rilevato: ImportError: ./hello_world.so: simbolo non definito: _ZNK12boost_1_47_06python7objects21py_function_impl_base9max_arityEv' – balki

+1

@balki: non hai collegato con Boost.Python. –

+0

Mi sono collegato a boost_python, ora ho "ImportError: libboost_python: impossibile aprire il file oggetto condiviso: nessun file o directory". Se esporto 'LD_LIBRARY_PATH =/path/to/boost_python_lib', funziona correttamente. Come posso specificare in cmdline? – balki

13

prendi il file 'hello_world.so' e crea un nuovo file python (nella stessa dir) chiamato 'hello_world.py'. Inserisci il codice qui sotto.

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__() 

ora è possibile importare questo hello_world come:

>>> import hello_world 
+2

Dovrebbe essere rinominato "\ __ bootstrap__", ad esempio "\ _bootstrap"? Ho passato molto tempo a cercare la documentazione per farlo, pensando che fosse una parola speciale riservata, ma non riuscivo a trovare nulla. Da https://www.python.org/dev/peps/pep-0008/#naming-conventions: \ __ double_leading_and_trailing_underscore__: oggetti o attributi "magici" che vivono in spazi dei nomi controllati dall'utente. Per esempio. \ __ init__, \ __ import__ o \ __ file__. Non inventare mai tali nomi; usarli solo come documentato. –

+0

siamo in grado di copiare, ma è possibile aggiungere alcuni dettagli sulle informazioni. Funziona. – user765443

+0

Ho provato questo con il readline del modulo. Mi capita di avere una versione n. 1 di Python (2.7.12) installata con apt-get, che ha readline, e un'altra versione # 2 (2.7.11), semplicemente espansa, che non lo fa. Così ho aggiunto un readline.py in una delle directory in sys.path per la versione # 2, e un link simbolico nella stessa dir in /usr/lib/python2.7/lib-dynload/readline.x86_64-linux-gnu. quindi dalla versione # 1. Ho ancora l'errore. –

Problemi correlati