Python嵌入C++详解

来源:互联网 发布:八爪鱼设置数据库 编辑:程序博客网 时间:2024/06/04 19:39

转载自:点击打开链接

今天终于搞清楚了c和python之间的相互调用问题,呵呵···

下面是c调用python的几个例子。

 

#include "python.h"  >//前面所做的一切配置都是为了调用这个头文件和相关库

int main(int argc,char** argv)
{
 Py_Initialize(); //该函数启动python解释器,使用python之前,算是初始化();

 //直接运行指令,指令都是字符串

 PyRun_SimpleString("from time import time,ctime\n"

 "print 'Hello World!'\n"

 "print 'Today is',ctime(time())\n");

 Py_Finalize();   //该函数关闭python解释器,算是扫尾,这个和Py_Initialize相对应的。

 return 0;
}

0. 坏境设置
把python的include/libs目录分别加到vc的include/lib directories中去。另外,由于python没有提供debug lib,体地说,就是没有提供python25_d.lib了。你可以自己编译python的源代码来得到python25_d.lib的,自己还没试过,呵呵。而且网上找了一下也没下载到。所以,如果你想要在debug下运行程序的话,你要把pyconfig.h(在python25/include/目录下)的大概是在283行,把pragma comment(lib,"python25_d.lib")改成pragma comment(lib,"python25.lib"),让python都使用非debug lib.

1. 开始编程了
#include <python.h>
第一步就是包含python的头文件

2. 看一个很简单的例子
1)python文件test.py,很简单的定义了一个函数

#Filename test.py
def Hello():
    print "Hello, world!"

2)cpp文件

#include <python.h> //包含头文件,在c++中嵌入python,这是必须的
int main()
{
Py_Initialize();

PyObject * pModule = NULL;
PyObject * pFunc   = NULL;

pModule = PyImport_ImportModule("test");  //这里是要调用的文件名
pFunc   = PyObject_GetAttrString(pModule, "Hello"); //这里是要调用的函数名
PyEval_CallObject(pFunc, NULL); //调用函数

Py_Finalize();

return 0;
}

第一步还是包含头文件

第二步,使用python之前,要调用Py_Initialize();这个函数进行初始化。
帮助文档中如是说:
The basic initialization function is Py_Initialize(). This initializes the table of loaded modules, and creates the fundamental modules __builtin__, __main__, sys, and exceptions. It also initializes the module search path (sys.path).

一开始一定要调用。

第三步,声明一些Python的变量,PyObject类型的。其实声明也可放在前面,这个倒是无所谓的。

第四步,import module,也就是你的脚本名字,不需要加后缀名,否则会出错的。

第五步,从你import进来的module中得到你要的函数
pFunc   = PyObject_GetAttrString(pModule, "Hello");
上面的例子已经够清楚的了,最后一个是你要得到的函数的名字

第六步,调用PyEval_CallObject来执行你的函数,第二个参数为我们要调用的函数的函数,本例子不含参数,所以设置为NULL。

第七步,调用Py_Finalize,这个根Py_Initialize相对应的。一个在最前面,一个在最后面。

代码如下,分别演示直接执行python语句、无返回无参数函数调用、返回单参数函数调用。返回多参数函数调用:

#include <Python.h>
#include <iostream>
using namespace std;

//执行python命令
void ExecPythonCommand()
{
 //直接执行
 PyRun_SimpleString("from time import time,ctime\n"
 "print 'Today is',ctime(time())\n");
}

//调用无参数函数
void InvokeNoParm()
{
 PyObject* pMod = NULL;
 PyObject* pFunc = NULL;
 //导入模块
 pMod = PyImport_ImportModule("Life");
 if(pMod)
 {
    //获取函数地址
    pFunc = PyObject_GetAttrString(pMod, "a");
    if(pFunc)
     {
    //函数调用
    PyEval_CallObject(pFunc, NULL);
     }
    else
     {
    cout << "cannot find function a" << endl;
     }
 }
 else
  {
     cout << "cannot find Life.py" << endl;
  }
}

//调用一参数函数
void InvokeWith1Parm()
{
 PyObject* pMod = NULL;
 PyObject* pFunc = NULL;
 PyObject* pParm = NULL;
 PyObject* pRetVal = NULL;
 int    iRetVal = 0;
 //导入模块
 pMod = PyImport_ImportModule("FuncDef");
 if(pMod)
 {
    pFunc = PyObject_GetAttrString(pMod, "square");
    if(pFunc)
     {
    //创建参数
    pParm = Py_BuildValue("(i)", 5);
    //函数调用
    pRetVal = PyEval_CallObject(pFunc, pParm);
    //解析返回值
    PyArg_Parse(pRetVal, "i", &iRetVal);
    cout << "square 5 is: " << iRetVal << endl;
     }
    else
     {
    cout << "cannot find function square" << endl;
     }
 }
 else
 {
    cout << "cannot find FuncDef.py" << endl;
 }
}

//调用多参数函数
void InvokeWith2Parm()
{
 PyObject* pMod = NULL;
 PyObject* pFunc = NULL;
 PyObject* pParm = NULL;
 PyObject* pRetVal = NULL;
 int    iRetVal = 0;
 //导入模块
 pMod = PyImport_ImportModule("add");
 if(pMod)
  {
     pFunc = PyObject_GetAttrString(pMod, "add");
     if(pFunc)
     {
    //创建两个参数
    pParm = PyTuple_New(2);
    //为参数赋值
    PyTuple_SetItem(pParm, 0, Py_BuildValue("i",2000));
    PyTuple_SetItem(pParm, 1, Py_BuildValue("i",3000));
    //函数调用
    pRetVal = PyEval_CallObject(pFunc, pParm);
    //解析返回值
    PyArg_Parse(pRetVal, "i", &iRetVal);
    cout << "2000 + 3000 = " << iRetVal << endl;
     }
     else
     {
    cout << "cannot find function square" << endl;
     }
  }
 else
  {
     cout << "cannot find add.py" << endl;
  }
}

int main(int argc, char* argv[])
{
 Py_Initialize(); //python 解释器的初始化

 ExecPythonCommand();
 InvokeNoParm();
 InvokeWith1Parm();
 InvokeWith2Parm();

 Py_Finalize();   // 垃圾回收、清除导入库
 return 0;
}

 

附:Python嵌入C/C++ (Python核心编程)

原创粉丝点击