如何从.so文件导入python模块?

bal*_*lki 27 c++ python boost-python

[me@hostname 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);
}

[me@hostnmae python]$ g++ -c -fPIC hello_world.cc -I/path/to/boost/headers -I/path/to/python/headers -o hello_world.o
[me@hostname python]$ g++ -shared -Wl,-soname,libhello_world.so -o libhello_world.so  hello_world.o
[me@hostname 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
>>>
Run Code Online (Sandbox Code Playgroud)

我创建了如上所示的.so文件但是我无法在python中导入.我错过了什么?

nam*_*mit 16

拿这个'hello_world.so'文件,并创建一个名为'hello_world.py'的新python文件(在同一目录中).将以下代码放入其中..

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__()
Run Code Online (Sandbox Code Playgroud)

现在你可以导入这个hello_world:

>>> import hello_world
Run Code Online (Sandbox Code Playgroud)

  • 是否应该将"\ __ bootstrap__"重命名为"\ ____""__ bootstrap"?我花了很多时间试图找到它的文档,认为这是一个特殊的保留字,但我找不到任何东西.来自https://www.python.org/dev/peps/pep-0008/#naming-conventions:\ __ double_leading_and_trailing_underscore__:"魔术"对象或属于用户控制的命名空间的属性.例如\ __ init __,_ __ import__或\ __ file__.不要发明这样的名字; 只记录使用它们. (2认同)
  • 我们可以复制,但你可以添加一些关于info的细节.它是如何工作的. (2认同)

Cat*_*lus 11

它必须被调用hello_world.so,而不是libhello_world.so.

  • 谢谢.现在我得到`ImportError:./ hello_world.so:未定义的符号:_ZNK12boost_1_47_06python7objects21py_function_impl_base9max_arityEv` (3认同)
  • @balki:您没有与 Boost.Python 链接。 (2认同)
  • `LD_LIBRARY_PATH =/path/to/boost_python_lib python`会很简单.如果可以的话,我建议你将符号链接`boost_python_lib`添加到`/ usr/local/lib`,然后你就可以轻松搞定.您还可以通过将`-Wl,-rpath =/path /传递给/ boost_python_lib`到编译器(实际上由链接器处理)来对`.so`文件中的路径进行硬编码. (2认同)