2012-06-10 32 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中導入。我錯過了什麼?如何從.so文件導入python模塊?

回答

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 =/path/to/boost_python_lib',它工作正常。我如何在cmdline中指定? – balki

13

取出'hello_world.so'文件並製作一個名爲'hello_world.py'的新python文件(在同一個dir中)。 把下面的代碼放在裏面..

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.How它的工作。 – user765443

+0

我試過這與模塊readline。我恰好有一個安裝了apt-get的python版本#1(2.7.12),它具有readline,另一個版本是#2(2.7.11),只是簡單地擴展了,而不是。所以我在sys.path中的一個目錄中添加了一個readline.py版本#2,並且在同一個目錄中添加了一個符號鏈接到/usr/lib/python2.7/lib-dynload/readline.x86_64-linux-gnu。所以從版本#1。我仍然得到錯誤。 –