Boost.Python是少数几个需要编译的Boost库,并且要求机器上已经装有python。编译的方法也非常简单,只需要在Boost目录下执行
bjam -toolset=msvc --with-python
编译好后就可以测试效果了。这里我使用$Boost/libs/python/example/quickstart的embedding.cpp做测试。最开始使用官方文档中提供的bjam方法
bjam toolset=msvc --verbose-test test
连接不成功。无奈使用VS2008来编译。
新建console工程,添加embedding.cpp,接着加入boost与python的include和libs路径。需要注意的是,boost的libs不是在$Boost/stage/lib那里,而是在$Boost/bin.v2/libs/python/build/msvc-9.0/debug/threading-multi。一切搞定好后,应该编译可以通过了。extending的工程也类似,只是要注意的是需要把extending.dll改名为extending.pyd。PS: *nix下直接.so就可以了,Mac用户需要把dylib改过来。
有时编译出来的没有dll文件,可以尝试在bjam中再添加一个参数 ‘link=shared’。
我使用scons来构建,下面是SConstruct文件内容
env = Environment(CPPPATH=['d:/tools/Python26/include', 'd:/Program Files/boost_1_40_0'], LIBPATH=['d:/Program Files/boost_1_40_0/stage/lib', 'd:/tools/Python26/libs'], CPPFLAGS=["/MDd", "/EHsc"]) env.Program('embedding.cpp') env.SharedLibrary('extending.cpp') Command("extending.pyd", "extending.dll", [Copy('extending.pyd', 'extending.dll'), Delete('extending.dll')])
显然,在 C++中嵌入python不是为执行速度;也不是因为Python的语法简洁,如果是小段代码,那么直接用C++实现一遍也不难,如是项目需要,那为什么不一开始就用Python,何必这么麻烦。嵌入Python最主要的目的是利用现成的python代码。
在C++中执行Python可理解为“内建python解释器",这一部分需要用到Python/C API。
做嵌入开发,一个很重要的一点是Python内置类型与c++的互换。C中的所有Python对象都是PyObject对象,Python/C 提供了很多函数简化它们之间的转换。有兴趣可以参考这篇文章 http://www.cnblogs.com/lovemo1314/archive/2011/05/14/2046496.html
BP在它的基础上做了一层封装,但是从表面看来这方面做得并不好(BP更倾向于extend而非embed)。不过我在文档上找不到它对整数、字符串、list是怎么处理的,只是隐约地看到下面类似的代码:
BOOST_TEST(python::extract<int>(global["number"]) == 42);
扩展的使用在test的目录下有非常多的示例,有需要时直接参考示例的做法。