如何在 Python 中编译、创建共享库和导入 c++ boost 模块

How to compile, create shared library, and import c++ boost module in Python

我看到网上有大量关于如何为 Python 编译 c++ 模块的信息。但问题是,实际上任何程序员都有自己的编译方式、自己的标志列表和其他技巧。所以,考虑到如此多种多样的技巧,我无法决定我应该使用哪种方法,此外我还有一些其他问题。这是我试过的:

// part of main.cpp file
....
BOOST_PYTHON_MODULE( orm ){
    class_<ORM>( "ORM",
    // other code goes here
}

我的第一个问题是如何在长运行中的Python中包含这个模块?我应该这样做吗:

  import orm

还是取决于编译过程中创建的目标文件的名称?

我的第二个问题是如何编译模块并为Python做准备?现在我这样做了:

$ g++ -I /usr/include/python2.7 -fpic -c -o main.o main.cpp

似乎应该有另一个额外的步骤来创建共享库,但我不确定如何做。顺便说一句,我把我的目标文件命名为 main.o 而不是 orm 或没有给它另一个名字可以吗?对某些人来说,我的问题是如何编译、构建共享库并将其包含在 Python 中(我希望我可以在那里使用 import orm)?

编辑

如果我这样做:

// part of main.cpp

BOOST_PYTHON_MODULE( orm ){
    class_<ORM>( "ORM",
    // other code goes here
}

$ g++ -I /usr/include/python2.7 -fpic -c -o orm.os main.cpp
$ g++ -o orm.so -shared orm.os -lboost_python -lpython2.7

然后我尝试在 python 中导入它时出现错误:

>>> import orm
...
ImportError: ./orm.so: undefined symbol: _ZNO3.....

那么,我做错了什么?我希望世界上至少有一个人知道答案。

编辑

我又做了一次尝试:

$ g++ -fpic -shared -o orm.so main.cpp `pkg-config --cflags --libs python` -I /usr/include/python2.7

当我再次这样做时:

>>> import orm

我仍然遇到同样的错误 undefined symbol blablabla。希望有人知道正确行事的神圣知识。

根据要求提供一个小的工作示例:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <boost/python.hpp>
#include <boost/python/raw_function.hpp>
#pragma GCC diagnostic pop


namespace python = boost::python;

class ORM
{
public:
  void foo(){std::cout << "foo" << std::endl;}
};

BOOST_PYTHON_MODULE(orm)
{
python::class_<ORM>("ORM")
    .def("foo", &ORM::foo)
;
}

构建命令行:

g++ -I /usr/include/python2.7 -fpic -c -o orm.o orm.cpp
g++ -o orm.so -shared orm.o -lboost_python -lpython2.7

运行 python 模块:

$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import orm
>>> o = orm.ORM()
>>> o.foo()
foo
>>> 

如果尝试导入模块返回 undefined symbol 错误,那么很可能在运行时使用的库版本与用于构建 python 模块的库版本不同。 您可以使用 ldd 打印共享库依赖项以查看是否一切正常,例如:ldd orm.so 并检查库的路径是否与用于构建模块的路径相同。