使用Boost.Python和Python 3.2的Hello World
我正在尝试用 Boost Python 将 Python 3.2 和 C++ 连接起来,但遇到了很多问题。最后我用 2.7 的库成功编译了,运行得很好,但用 3.2 的库就不行了。
这是我的 C++ 代码:
#include <iostream>
using namespace std;
void say_hello(const char* name) {
cout << "Hello " << name << "!\n";
}
int main(){return 0;}
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello)
{
def("say_hello", say_hello);
}
用 2.7 的库编译时一切正常,但用 3.2 的库时,我遇到了很多来自 libboost_python.so 的未定义引用错误。
除此之外,我还写了一点 Python 代码来让它工作:
from distutils.core import setup
from distutils.extension import Extension
setup(name="PackageName",
ext_modules=[
Extension("hello", ["testBoost.cpp"],
libraries = ["boost_python"])
])
这段代码可以用 Python 3.2 或 2.7 的构建来创建一个 so 文件,但当我打开 Python 3 的解释器并尝试导入这个 so 文件时,又出现了来自 libboost_python.so 的未定义符号 PyClass_Type 的错误。有没有什么想法?Boost Python 和 Python 3.x 兼容吗?
如果这些信息有用,这是我尝试用 3.2 编译的代码:
$ g++ testBoost.cpp -I/usr/include/python3.2 -I/usr/local/include/boost/python -lboost_python -lpython3.2mu
/tmp/ccdmU1Yu.o: In function `PyInit_hello':
testBoost.cpp:(.text+0xc2): undefined reference to `boost::python::detail::init_module(PyModuleDef&, void (*)())'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_Size'
/usr/local/lib/libboost_python.so: undefined reference to `PyFile_FromString'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_Type'
/usr/local/lib/libboost_python.so: undefined reference to `PyInt_Type'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_FromString'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_FromStringAndSize'
/usr/local/lib/libboost_python.so: undefined reference to `Py_InitModule4_64'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_FromFormat'
/usr/local/lib/libboost_python.so: undefined reference to `PyNumber_Divide'
/usr/local/lib/libboost_python.so: undefined reference to `PyNumber_InPlaceDivide'
/usr/local/lib/libboost_python.so: undefined reference to `PyInt_AsLong'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_InternFromString'
/usr/local/lib/libboost_python.so: undefined reference to `PyClass_Type'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_AsString'
/usr/local/lib/libboost_python.so: undefined reference to `PyInt_FromLong'
/usr/local/lib/libboost_python.so: undefined reference to `PyFile_AsFile'
collect2: ld returned 1 exit status
而 Python 3 解释器给出的错误是:
File "<stdin>", line 1, in <module>
ImportError: /usr/local/lib/libboost_python.so.1.47.0: undefined symbol: PyClass_Type
谢谢你的帮助!
4 个回答
上面的C++代码会编译成一个模块,使用的是以下命令:
$ g++ testBoost.cpp -I/usr/include/python3.2 -I/usr/local/include/boost/python -lboost_python3 -lpython3.2mu -o hello.so -shared
这个编译命令中加了 -lboost_python3
和 -shared
,同时也遵循了Python扩展模块的命名规则。如果你还没有安装 python3-dev
包,记得要安装,并且要用Python3来配置、构建和安装Boost库。
在Python 3中,我可以这样做:
$ python3
Python 3.2 (r32:88445, Mar 25 2011, 19:28:28)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import hello
>>> hello.say_hello('bill')
Hello bill!
>>>
到这个时候,你就可以开始使用了。
我遇到了完全一样的问题,使用的是Ubuntu 12.04。我安装了这个库的1.48版本,然后需要链接 libboost_python-py32.so
而不是 libboost_python.so
。这样做之后,链接错误就消失了。
虽然这个讨论有点老,但还是记录一下:
修改 project-config.jam 文件,把 Python 版本改成你自己电脑上的版本。
# Python configuration
using python : 3.4 : /usr ;
然后开始构建 Boost 库:
./b2 clean
./b2 --with-python link=static cxxflags="-std=c++11 -fPIC" variant=release stage
./b2 --with-python link=static cxxflags="-std=c++11 -fPIC" variant=release install
后面的命令需要超级用户权限。接着,进入包含扩展的 C++ 代码的文件夹:
g++ -std=c++11 hellopy.cpp -I/usr/include/python3.4 -I/usr/local/include/boost/python -lboost_python3 -o hello.so -shared -fPIC
这样你就可以在你的 Python 环境中导入 hello 了。