to myself 的分类学习日志

做自己想做的事
posts - 232, comments - 6, trackbacks - 0, articles - 0

python与C或者C++的混合编程

Posted on 2010-11-30 19:10 kongkongzi 阅读(9406) 评论(0)  编辑 收藏 引用 所属分类: python
python
pdf book: http://www.oschina.net/bbs/thread/9780


python与C或者C++的混合编程: 包括在python中调用C++中的API,和在C++中调用python脚本。
实战构建Python和C++混合系统: http://blog.csdn.net/mythma/archive/2009/09/15/4556155.aspx


用Python编写运行Hello World程序: http://hi.baidu.com/rongjch/blog/item/1f548851e078cb8e8d543032.html/cmtid/5e9f7b600ef93dd18cb10d6a

C/C++中如何调用Python方法: http://bambooice.blog.hexun.com/37655834_d.html

#include "Python.h"

编译选项, 需要手动指定Python 的include 路径, 和链接接路径,
代码:

g++ PythonConsole.cpp -I/usr/local/include/python2.7 -L/usr/local/lib/python2.7 -lpython2.7

C语言的编辑方法
gcc emu.c -L/usr/lib/python2.2/config -lpython2.2 -lpthread -lm -ldl -lutil


/usr/local/include/python2.7/
/usr/local/lib/python2.7/
/usr/local/share/man/man1/python2.7.1


C/C++中如何调用python方法

C++中调用Python脚本的意义就不讲了,至少你可以把它当成文本形式的动态链接库,

需要的时候还可以改一改,只要不改变接口, C++的程序一旦编译好了,再改就没那么方便了

先看Python的代码
代码:

#test function

def add(a,b):

    print "in python function add"

    print "a = " + str(a)

    print "b = " + str(b)

    print "ret = " + str(a+b)

    return



def foo(a):

    print "in python function foo"

    print "a = " + str(a)

    print "ret = " + str(a * a)

    return



把上面的Python代码存为pytest.py

接下来是c++ 的代码
代码:

#include "Python.h"

int main(int argc, char** argv)
{
    // 初始化Python
    //在使用Python系统前,必须使用Py_Initialize对其
    //进行初始化。它会载入Python的内建模块并添加系统路
    //径到模块搜索路径中。这个函数没有返回值,检查系统
    //是否初始化成功需要使用Py_IsInitialized。

    Py_Initialize();

    // 检查初始化是否成功
    if ( !Py_IsInitialized() )
    {
        return -1;
    }

    // 添加当前路径
    //把输入的字符串作为Python代码直接运行,返回0
    //表示成功,-1表示有错。大多时候错误都是因为字符串
    //中有语法错误。
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");
    PyObject *pName,*pModule,*pDict,*pFunc,*pArgs;

    // 载入名为pytest的脚本
    pName = PyString_FromString("pytest");
    pModule = PyImport_Import(pName);
    if ( !pModule )
    {
        printf("can't find pytest.py");
        getchar();
        return -1;
    }
    pDict = PyModule_GetDict(pModule);
    if ( !pDict )
    {
        return -1;
    }

    // 找出函数名为add的函数
    pFunc = PyDict_GetItemString(pDict, "add");
    if ( !pFunc || !PyCallable_Check(pFunc) )
    {
        printf("can't find function [add]");
        getchar();
        return -1;
    }

    // 参数进栈
    *pArgs;
    pArgs = PyTuple_New(2);

    //  PyObject* Py_BuildValue(char *format, ...)
    //  把C++的变量转换成一个Python对象。当需要从
    //  C++传递变量到Python时,就会使用这个函数。此函数
    //  有点类似C的printf,但格式不同。常用的格式有
    //  s 表示字符串,
    //  i 表示整型变量,
    //  f 表示浮点数,
    //  O 表示一个Python对象。

    PyTuple_SetItem(pArgs, 0, Py_BuildValue("l",3));
    PyTuple_SetItem(pArgs, 1, Py_BuildValue("l",4));

    // 调用Python函数
    PyObject_CallObject(pFunc, pArgs);

    //下面这段是查找函数foo 并执行foo
    pFunc = PyDict_GetItemString(pDict, "foo");
    if ( !pFunc || !PyCallable_Check(pFunc) )
    {
        printf("can't find function [foo]");
        getchar();
        return -1;
    }

    pArgs = PyTuple_New(1);
    PyTuple_SetItem(pArgs, 0, Py_BuildValue("l",2)); //

    PyObject_CallObject(pFunc, pArgs);


    Py_DECREF(pName);
    Py_DECREF(pArgs);
    Py_DECREF(pModule);

    // 关闭Python
    Py_Finalize();
    return 0;
}


编译选项, 需要手动指定Python 的include 路径, 和链接接路径,
代码:

g++ PythonTest.cpp -I/usr/local/include/python2.7 -L/usr/local/lib/python2.7 -lpython2.7 -lpthread -ldl -lm -lutil

如果你的Python 版本号与我的不同,请修改为你自己的版本号

原文地址:http://coredump.blog.bokee.net/bloggermodule/blog_printEntry.do?id=909014


参考:
1,Python 中文社区: http://python.cn/




/usr/local/include/python2.7/
/usr/local/lib/python2.7/
/usr/local/share/man/man1/python2.7.1


/usr/bin$ ls python* -l
lrwxrwxrwx 1 root root       9 2010-10-21 16:20 python -> python2.6
lrwxrwxrwx 1 root root       9 2010-10-21 16:20 python2 -> python2.6
-rwxr-xr-x 1 root root 2230352 2009-10-20 11:48 python2.6


/usr/bin$ which python
/usr/local/bin/python






import gtk ImportError: No module named gtk

/usr/lib/python2.5/site-packages
/usr/local/lib/python2.7/site-packages
/usr/local/lib/python2.6/site-packages

This directory exists so that 3rd party packages can be installed
here.  Read the source for site.py for more details.

site.py


安装时候 ,注意把 gtk 选上



>>> import sys
>>> print sys.path
['', '/usr/local/lib/python27.zip', '/usr/local/lib/python2.7', '/usr/local/lib/python2.7/plat-linux2', '/usr/local/lib/python2.7/lib-tk', '/usr/local/lib/python2.7/lib-old', '/usr/local/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/site-packages']


>>> print sys.path
['', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old', '/usr/lib/python2.6/lib-dynload', '/usr/lib/python2.6/dist-packages', '/usr/lib/python2.6/dist-packages/PIL', '/usr/lib/python2.6/dist-packages/gst-0.10', '/usr/lib/pymodules/python2.6', '/usr/lib/python2.6/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.6/gtk-2.0', '/usr/local/lib/python2.6/dist-packages']
>>>

显示python的site-packages路径:
$ python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/usr/local/lib/python2.7/site-packages


Configuring additional built-in modules
---------------------------------------

Starting with Python 2.1, the setup.py script at the top of the source
distribution attempts to detect which modules can be built and
automatically compiles them.  Autodetection doesn't always work, so
you can still customize the configuration by editing the Modules/Setup
file; but this should be considered a last resort.  The rest of this
section only applies if you decide to edit the Modules/Setup file.
You also need this to enable static linking of certain modules (which
is needed to enable profiling on some systems).




手动编译安装python后,ibus不能用
我手动编译安装python2.6,之后ibus就不能用了。
出现下面这个

Traceback (most recent call last):
File "/usr/share/ibus/setup/main.py", line 28, in <module>
import gtk
ImportError: No module named gtk


但是之前python2.5.4一直没事的说,不会新编译了python之后,所有与之相关的软件都要重新编译吧??

咳.. 好像是的..
至少python的模块都要重新编译,比如pygtk什么的


是的,重新编译 python,必须编译所有 python 模块。要编译 pygtk,必须编译一大堆的依赖。

所以,一般如果只是想要一个自己的 python,编译到与系统不同的目录并把python主程序改名是个方案。

在Linux上安装pygtk

由于项目需要,要在linux上为python 2.6.5安装pygtk包。本来以为很简单的一件事,或使用easy_install安装,或源代码编译安装,都很简单;不曾想搞了一天,愣是没有搞定,期间的麻烦,安装文件的左右依赖不胜其烦呀。

  首先,在安装pygtk使用easy_install是行不通的。因为不只是要编译C代码,更需要检测机器状况,因此必须以进行常规源代码编译的方式进行安装,如configure、make、make install等。

  另外,安装pygtk需要依赖于PyGObject,其又依赖于GObject-Introspection,而要安装GObject- Introspection,又必须安装GLIB,安装GLIB可能会安装升级gettext,因为旧版的gettext不能识别GLIB中的一些新方法。另外,安装这些包时还会要求版本号不能低于某某。于是,错综复杂,安装、卸载,最终还是没有成功。

  刚刚看了一下pygtk官网,似乎在windows下也能安装。这个周末找个时间再好好研究一下,争取能安装成功pygtk。

python-gobject



只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理