转载自:点击打开链接
今天终于搞清楚了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的头文件
2. 看一个很简单的例子
1)python文件test.py,很简单的定义了一个函数
#Filename test.py
def Hello():
print "Hello, world!"
2)cpp文件
#include
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
#include
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核心编程)