您的位置:首页 > 编程语言 > Python开发

boost python的使用

2012-06-08 13:58 176 查看
之前的文章 Python扩展模块实现中,介绍了如何使用c++编写python的扩展模块,现在我们有了新的选择,因为Boost提供了Python库,我们可以很容易的使用它来在C++应用程序中嵌入Python(目前有些功能可能还需要调用Python
API);也可以使用它来扩展Python,在这方面的功能更强大。

1. Boost Python库的编译
boost中的组件,大部分都不需要编译就可以直接使用,但有些不是,Python库就是“有些”中的一个。因此使用boost python库的方式有两种:
(1)使用bjam编译python库。命令是:bjam --toolset=msvc --with-python --build-type=complete stage, --toolset是设置使用的编译工具,这里使用的是visual studio, --with-python表示编译python模块,如果你要编译**模块,将python改成**就可以了,--build-type这里设置complete完成编译,
这里要吐槽一下,网上还有有些书上说 build-type 不设置也可以,不设置就是默认编译为Release模式,这就坑爹了,默认是Realease没错,姑且不说我们写的程序是Debug的,就是是Release,它也得要生成dll吧,不然程序怎么能完成”链接(link)“,写过dll的都知道没dll会出一堆没法找到外部链接的错啦=。=,好吧!也可能是我版本跟大家的不一样,我是1.47的,这里要说这个build-type要设置为完成编译,不然它不生成dll,而且.lib命名也不一样,还得自己该,设置complete就OK了。
这里还有一个地方需要注意就是,如果你之前安装boost的时候,不是自己手工编译成功的,而是采用偷懒采用“boostpro”(不好意思,名字忘了)提供的安装包,进行安装的,那么这里你可能会需要一些麻烦,因为这样的话你可能对上面的bjam不甚熟悉,我就是这样滴,在网上查资料,它会教你到tools目录啥啥子那里找啥啥,然后***,遗憾的是,你的boost根目录下没有tools,我的就是这样,用安装包的坏处,可别着急着卸了重新自己编译,不需要,其实安装包也就是帮你装了哪些需要编译的包而已,你只需在这基础上编译python或者其他需要编译的包就是了,下载一个跟你的版本一样的boost发行版源码,将里面的tools目录拷贝到你的boost根目录,然后照上面所说和网上的教程做就可以完成编译了。

(2)采用源码嵌入工程编译的方式。方法是新建.cpp源文件,然后添加下面的代码,采用这种方式使用的时候需要添加如下的宏定义#define BOOST_PYTHON_SOURCE:
#define BOOST_PYTHON_SOURCE

#include <libs/python/src/numeric.cpp>
#include <libs/python/src/list.cpp>
#include <libs/python/src/long.cpp>
#include <libs/python/src/dict.cpp>
#include <libs/python/src/tuple.cpp>
#include <libs/python/src/str.cpp>
#include <libs/python/src/slice.cpp>

#include <libs/python/src/converter/from_python.cpp>
#include <libs/python/src/converter/registry.cpp>
#include <libs/python/src/converter/type_id.cpp>
#include <libs/python/src/object/enum.cpp>
#include <libs/python/src/object/class.cpp>
#include <libs/python/src/object/function.cpp>
#include <libs/python/src/object/inheritance.cpp>
#include <libs/python/src/object/life_support.cpp>
#include <libs/python/src/object/pickle_support.cpp>
#include <libs/python/src/errors.cpp>
#include <libs/python/src/module.cpp>
#include <libs/python/src/converter/builtin_converters.cpp>
#include <libs/python/src/converter/arg_to_python_base.cpp>
#include <libs/python/src/object/iterator.cpp>
#include <libs/python/src/object/stl_iterator.cpp>
#include <libs/python/src/object_protocol.cpp>
#include <libs/python/src/object_operators.cpp>
#include <libs/python/src/wrapper.cpp>
#include <libs/python/src/import.cpp>
#include <libs/python/src/exec.cpp>
#include <libs/python/src/object/function_doc_signature.cpp>


经自己的亲身试验这种方式,如果用的vc版本跟boost库使用的版本不一样的,很容易需要编译错误,很容易理解,你在vc6.0写的功能,放到2005编译可能就通不过。

2. 嵌入Python
还记得在c程序中执行python语句的标准流程:
(1)调用Python API函数 Py_Initialize()启动Python解释器;
(2)调用python语句;
(3)使用Py_Finalize()来清除解释器环境。
在类的初始化和析构函数中来完成Python解释器的初始化和清除环境工作:
class ds_py_init{
public:
ds_py_init(int sigs=1){
assert(sigs == 0 || sigs == 1);
Py_InitializeEx(sigs);
}

~ds_py_init(){
Py_Finalize();};

bool isInitialized()
{
return Py_IsInitialized();
}

const char* version()
{
return Py_GetVersion();
}
};


测试嵌入python:

/* python */
//#define BOOST_PYTHON_SOURCE
#pragma comment(lib,"python27.lib")
#include <boost/python.hpp>

#include <iostream>
#include <string>
#include "ds_py_init.h"

//naming space
using namespace std;
using namespace boost::python;

int main()
{
/* python */
ds_py_init pinit;
object i(10);
i=10*i;
cout<<extract<int>(i)<<endl;

object s("string");
string str = extract<string>(s*5);
cout<<str<<endl;

string p_cmd = "for i in [2,3,4]: print i";
cout<<"execute python command : "<<p_cmd<<endl;
exec(p_cmd.c_str());

return 0;
}


输出结果:



3. 扩展Python
扩展Python,知道使用BOOST_PYTHON_MODULE宏定义Python模块名,模块名需要和你创建的DLL工程的名字相同,而如果你想向Python导出的函数是有参数的,那么你需要使用Python库提供的类arg,它还提供了便捷的args。知道了如何编写导出函数,导出类,导出属性等也可以参考网上教程,boost文档,欢迎讨论,欢迎指教。

(以上内容为参考网上资料及相关书籍经自己实践总结所得笔记,欢迎交流学习)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: