还是先说一下背景吧,之前有写过C,C++代码中调用python脚本,但也仅是停留在浅尝辄止的地步,这次由于在fuload中要实现调用python的脚本,所以继续深入了解了一下。
提前打好招呼,这篇文章有点长,但是信息量也比较大,如果感兴趣希望能耐心读下去。
另外,文章中的代码都可以直接到fuload项目下看到:
http://code.google.com/p/fuload/source/browse/#svn/trunk/src/slave/py_module
先来看一下so的cpp文件:

然后看一下其调用的fl_module.py:

代码逻辑都是比较简单的,就不详细解释了,只列出几个链接,大家有兴趣可以看一下:
PyObject的常用函数
将python类型转换成C类型
通过C类型生成python类型
Py_BuildValue的说明

OK,其实最郁闷的并不是在代码的编写上,而是在makefile的编写上。
由于一开始想先通过编译成可执行程序来测试,所以makefile如下:

但是编译出来的程序在执行的时候会报如下错误:

后来发现这个问题是有两种解决方案:
1.如果python在编译安装的时候,没有使用:

那么就会造成在/usr/local/lib/目录下只有libpython2.7.a而没有libpython2.7.so,这个时候需要给makefile加一个参数:

即makefile变成:

成功~
2.我们也可以在python编译安装的时候就加上

这样原来的makefile不用做任何更改也是可以用的。
用man看了一下:

OK,这样可执行程序就没有问题了,但是关键我们要实现的是编译一个so。
————————————-我是分割线———————————–
无论我们是否已经用

编译了python,为保险起见,都用如下makefile编译so:

用如下代码加载so:

会发现报如下错误:

这里可真是苦了我了,在网上遍寻原因未果,后来终于突发奇想,原来是加载so的调用有问题,改成如下方式后正常:

搜到的解释如下:

OK,到此为止,我们的程序总算是调通了,文章很长,但是相信也是值得的.
这里再附赠一个函数,当调用python脚本失败,打印异常信息(参考自:http://www.cppblog.com/why/archive/2010/11/08/132999.html):

最近的一些技术整理(20120109)

前段时间一直没写博客,昨天更新了一篇,今天突然又来了兴致,那就再更新一篇吧(所以说啊,治疗拖延症最好的方法就是现在开始做) 这篇还是一些技术的整理,...

阅读全文

C++模板的几个应用

C++的模板其实是个挺纠结的东西,用的不好的话,编译的一堆错误够你调到崩溃,但要是用的好呢,又确实非常方便,我们来看看 一.获取数组长度 比如 ...

阅读全文

又见C++诡异问题

用C++越久,越是觉得C++太多陷阱,真是防不胜防。 我们看这样一段代码: C++ #include <stdio.h> using namespace std; ...

阅读全文

11则回应给“C,C++中调用python脚本(2)-高级应用”

  1. iCyOMiK说道:

    这次的比上次长很多,先Mark一下,回头再看~谢谢。

    [回复]

  2. ptrjeffrey说道:

    赞一个
    我的情况和楼主一样,在可执行程序里面一点问题没有,不过编译成so以后就出现
    ImportError: /usr/local/lib/python2.5/lib-dynload/time.so: undefined symbol: pyExec_IOError
    想了很多办法都不行,看到了楼主的文章,试试着改了一下,结果果然OK!
    欢迎交流

    [回复]

  3. ptrjeffrey说道:

    为什么评论不上

    [回复]

  4. ptrjeffrey说道:

    赞一个
    楼主帮我解决了大问题
    我在so中去调用python的东东的时候也遇到import time 就有问题,出现
    ImportError: /usr/local/lib/python2.5/lib-dynload/_socket.so: undefined symbol: PyExc_IOError
    用了楼主的办法问题解决.哈哈

    [回复]

  5. flyliying说道:

    可以尝试boost.python

    [回复]

    Dante 回复:

    呃,为什么不用python原生的,非要去搞别人封装过的呢。。

    [回复]

  6. aaqqxx说道:

    如果调用的模块里面使用了matplotlib里面的show().,好像就只能显示一次,能不能很好的解决呢?
    #include
    #include

    void test2()
    {
    // int b;
    Py_Initialize();
    PyRun_SimpleString(“from matplotlib.pyplot import plotfile\n”
    “from pylab import show\n”
    “plotfile(‘/home/huskier/Desktop/data’)\n”
    “show()\n”);
    Py_Finalize();
    }

    int
    main(int argc,char *argv[])
    {
    test2();
    test2();
    return 0;
    }

    一直段错误,怎么好解决呢?

    [回复]

    aaqqxx 回复:

    #include
    #include

    [回复]

    Dante 回复:

    呃,这个我也没法直接给你解答,对照一下文章的代码和编译参数,如果还是不行的话,只能google看一下有没相同问题的了。。好像之前是有同学报段错误的。

    [回复]

    madper 回复:

    先说一下, 我什么都不会, 然后, 段错误可以考虑用valgrind来跑一下, 起码可以定位是哪里出现的段错误. 然后再考虑怎么解决…

    [回复]

  7. 7asswd说道:

    赞。看了这个文章,解决了我的BUG.

    [回复]

发表评论