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

Я создал файл .so, как показано выше, но я не могу импортировать внутри python. что мне не хватает?Как импортировать модуль python из .so-файла?

ответ

8

Его надо называть hello_world.so, а не libhello_world.so.

+2

спасибо. Теперь я получаю 'ImportError: ./hello_world.so: undefined symbol: _ZNK12boost_1_47_06python7objects21py_function_impl_base9max_arityEv' – balki

+1

@balki: Вы не связывались с Boost.Python. –

+0

Я связан с boost_python, теперь я получаю 'ImportError: libboost_python: не могу открыть файл общих объектов: нет такого файла или каталога'. Если я экспортирую 'LD_LIBRARY_PATH =/путь/в/boost_python_lib', он отлично работает. Как указать в cmdline? – balki

13

возьмите этот файл «hello_world.so» и создайте новый файл python (в том же каталоге), который называется «hello_world.py». Вставьте в него код внизу ...

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

теперь вы можете импортировать этот hello_world как:

>>> import hello_world 
+2

Следует ли переименовать «\ __ bootstrap__», скажем, «\ _bootstrap»? Я потратил много времени на то, чтобы найти документацию, считая, что это специальное зарезервированное слово, но я ничего не мог найти. Из https://www.python.org/dev/peps/pep-0008/#naming-conventions: \ __ double_leading_and_trailing_underscore__: «волшебные» объекты или атрибуты, которые находятся в управляемых пользователем пространствах имен. Например. \ __ init__, \ __ import__ или \ __ file__. Никогда не изобретайте такие имена; используйте их только как задокументированные. –

+0

мы можем скопировать, но вы можете добавить дополнительную информацию о info.Как это работает. – user765443

+0

Я пробовал это с помощью модуля readline. У меня, вероятно, есть версия python # 1 (2.7.12), установленная с apt-get, которая имеет readline и другую версию № 2 (2.7.11), просто расширена, а это не так. Поэтому я добавил readline.py в один из каталогов в sys.path для версии №2 и символическую ссылку в том же каталоге в /usr/lib/python2.7/lib-dynload/readline.x86_64-linux-gnu. поэтому из версии №1. Я все еще получаю ошибку. –