2015-07-22 41 views
2

我发现Web上有大量关于如何为Python编译C++模块的信息。但问题是,实际上任何程序员都有自己的编译方式和他自己的标志列表以及其他技巧。所以,考虑到各种各样的技巧,我不能决定我应该使用哪种方法,除此之外我还有其他一些问题。这是我试过的:如何在Python中编译,创建共享库并导入C++ boost模块

// 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。希望有人知道这样做的正确理由。

+0

尝试'ldd orm.so' – doqtor

+0

非常丰富))几乎就像“尝试一些东西”。如何尝试?请你详细说明一下这件事吗?我应该添加'ldd'到我的最后一个命令,还是应该在所有命令之后运行它,或者在什么地方? – Jacobian

+0

如果你可以提供一个微小的工作示例作为答案,那将是非常感谢和价值+100500的声誉,因为它似乎是许多程序员必须采取的基本步骤。 – Jacobian

回答

3

按照要求一个微小的工作例如:

#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错误,那么很可能在运行时存在不同版本的l正在使用的库比用于构建python模块的库更为常用。 如果一切正常,您可以使用ldd来打印共享库依赖关系以查看是否正常,例如:ldd orm.so并检查库的路径是否与用于构建模块的路径相同。

+0

谢谢,先生!现在,它非常丰富! – Jacobian

+1

@Jacobian这是一个基于这个答案的在线[demo](http://coliru.stacked-crooked.com/a/215c86c2ffbde9bf)。 –