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

Ich erstellte die .so-Datei wie oben gezeigt, aber ich kann nicht innerhalb von Python importieren. Was vermisse ich?Wie importiert man das Python-Modul aus der .so-Datei?

Antwort

8

Es muss hello_world.so, nicht libhello_world.so genannt werden.

+2

Dank. Jetzt bekomme ich 'ImportError: ./hello_world.so: undefiniertes Symbol: _ZNK12boost_1_47_06python7objects21py_function_impl_base9max_arityEv' – balki

+1

@balki: Sie haben keine Verbindung mit Boost.Python hergestellt. –

+0

Ich verlinkt gegen boost_python, jetzt bekomme ich 'ImportError: libboost_python: kann keine gemeinsame Objektdatei öffnen: Keine solche Datei oder Verzeichnis'. Wenn ich 'LD_LIBRARY_PATH =/Pfad/zu/boost_python_lib 'exportiere, funktioniert es gut. Wie definiere ich in cmdline? – balki

13

nehmen Sie die Datei 'hallo_world.so' und machen Sie eine neue Python-Datei (im selben Verzeichnis) namens 'hallo_world.py'. Geben Sie den folgenden Code ein ...

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

jetzt können Sie diese hello_world als importieren:

>>> import hello_world 
+2

Soll "\ __ bootstrap__" in "\ _bootstrap" umbenannt werden? Ich habe viel Zeit damit verbracht, die Dokumentation dafür zu finden, weil ich dachte, es wäre ein spezielles, reserviertes Wort, aber ich konnte nichts finden. Von https://www.python.org/dev/peps/pep-0008/#naming-conventions: \ __ double_leading_and_trailing_underscore__: "magische" Objekte oder Attribute, die in benutzergesteuerten Namespaces leben. Z.B. \ __ init__, \ __ import__ oder \ __ file__. Erfinde niemals solche Namen; verwende sie nur wie dokumentiert. –

+0

können wir kopieren, aber können Sie einige Details über info hinzufügen. Wie funktioniert es? – user765443

+0

Ich habe das mit dem Modul readline probiert. Ich habe zufällig eine Python-Version # 1 (2.7.12) installiert mit apt-get, die readline hat, und eine andere Version # 2 (2.7.11), einfach erweitert, was aber nicht der Fall ist. Also habe ich ein readline.py in einem der Verzeichnisse in sys.path für Version 2 und einen Symlink im selben Verzeichnis zu /usr/lib/python2.7/lib-dynload/readline.x86_64-linux-gnu hinzugefügt. also ab Version # 1. Ich bekomme immer noch den Fehler. –

Verwandte Themen