昨天总结了利用boost.python在python中调用C++函数http://blog.csdn.net/sunshine_in_moon/article/details/51124114。今天总结一下在C++中嵌入python的各种坑。
和上篇博客一样,先给大家一些博客连接,是我查找的资料:
第一篇,特点讲述里C++中调用python的两种方法,我主要是参照第二种方法。http://www.cnblogs.com/rocketfan/archive/2009/11/15/1603400.html
第二篇,特点详细讲述了Python C API 各种函数,和两个详细的例子,但是没有使用boost.python。http://blog.csdn.net/magictong/article/details/8947892
第三篇,特点讲述了在C++中调用含有不定长参数(tuple)和关键字参数(dict)的python函数的方法。http://www.cnblogs.com/rocketfan/archive/2009/11/17/1604241.html
第四篇,特点例子简单,但是我没有成功。http://blog.chinaunix.net/uid-20442304-id-212922.html
第五篇,特点一个非常完整的例子,但使用的是Python C API。http://www.cnblogs.com/Hisin/archive/2012/02/27/2370590.html
第六篇,特点详细介绍了eval,exec,execfile,compile四个函数。http://skandgjxa.blog.163.com/blog/static/1415298201010262403483/
好了,该说说我碰到的坑了。
开始前先说明几点:
1、一定要记住,有了boost.pyhon并不代表完全放弃了Python C API,boost.python只是简化了Pyhon C API中一部分工作,相信以后会有改进。
2、使用Pyhon C API 需要使用Python.h Python27.lib 这两个文件在你安装的python路径下。
3、使用boost.python 需要包含头文件<boost/python.hpp> 和相应的库,自己添加就好。这里我发现一个问题,我没有添加boost的静态库,也没有问题,可能是从我的环境变量里找到的路径,但是还是建议大家手动添加。
OK!先贴出代码,再逐个说明大坑。
<span style="font-size:18px;">#include <boost/python.hpp>
#include <iostream>
#include <Python.h>
using namespace std;
using namespace boost::python;
int main(int argc, char* argv[])
{
Py_SetPythonHome("D:/Anaconda2");//手动添加python路径
Py_Initialize();//初始化python解释器
boost::python::object main_module = import("__main__");
boost::python::object main_namespace = main_module.attr("__dict__");
boost::python::object Text = exec_file("E:/test/python/x64/Release/text_process.py",main_namespace,main_namespace);
string dir_path = "E:/wu_test/pictures";
string image_list = "E:/test/python/python/image_list.txt";
//Text.attr("creat_imagelist_NoLabel")(dir_path, image_list);
</span><pre name="code" class="cpp"><span style="white-space:pre"> </span>boost::python::object imagelist = main_namespace["creat_imagelist_NoLabel"];
imagelist(dir_path, image_list);
return 0;}
第一个坑,如果你按照很多博客上提到的上来就是如下,初始化Python解释器,你很有可能遇到这个坑,ImportError:No module named site
<span style="font-size:18px;">Py_Initialize();</span>
出现这个致命错误的原因是python解释器无法找python库。解决方法有两种:
方法1.在调用Py_Initialize之前,手动设置python搜索目录:Py_SetPythonHome("D:/Anaconda2")。Py_SetPythonHome 是一个python C API 函数,因此,我们也看出不能只用boost.python库。
方法2.添加python的环境变量:PYTHONPATH
此处参考:http://blog.csdn.net/you_lan_hai/article/details/8592697
第二个坑,execfile函数的使用。说实话,我还没有研究太明白,我只能按照别人的例子依葫芦画瓢。但有一点提醒大家,在加载.py文件时,如果不知道该把.py文件放在哪里,那就和我一样使用绝对路径吧,另外.py后缀不能丢。
第三个坑,就是怎样调用.py文件中的子函数呢?
<span style="font-size:18px;"><span style="white-space:pre"> </span>boost::python::object imagelist = main_namespace["creat_imagelist_NoLabel"];//通过字典的方式,从main_namespace中取出子函数(子函数的名字是关键字),这样imagelist,就是python中的creat_imagelist_NoLabel子函数了。
imagelist(dir_path, image_list);//既然imagelist=creat_iamgelist_NoLabe,那么我们按照python中的使用方法,使用imagelist就可以了</span>
第四个坑,我得到了正确的结果,但是有个报错没有解决,如果大家有解决办法,希望留言。
就是这个IOError的错误。由于结果正确我就没有深究,给大家几个链接供参考:
http://www.iplaypython.com/jinjie/ioerror.html
http://www.tuicool.com/articles/yAFneq