C++调用Python

一:安装相关

首先要安装pydev,安装方法如图:


并且我们编译时要加上上述相关编译指令。(感谢这位仁兄)

二:函数调用

Python提供了一些特殊的API包装来供C++调用。

void Py_Initialize(void)
该函数初始化Python解释器,如果初始化失败,继续下面的调用会出现错误。该函数无返回值。


int Py_IsInitialized(void)
我们可与凭借这个函数来检测是否初始化成功。返回0表示未初始化。


void Py_Finalize()
这个函数析构Python解释器,相当于dtor,会释放Python解释器所占用的资源。


int PyRun_SimpleString(const char* command)
该函数实际上是一个宏,执行一小段Python代码,就好像在__main__函数里面执行一样。

比如:PyRun_SimpleString("import sys")


Pyobject* PyImport_Module(char *name)
导入一个Python模块,参数name可以使*.py的文件名。类似Python内建函数import。


PyObject* PyModule_GetDict(PyObject *module)
相当于Python模块对象的__dict__属性,得到模块名称空间下的字典对象。


Pyobject* PyRun_String(const char* str, int start, PyObject* globals, PyObject* locals)
执行一段Python代码


int PyArg_Parse(PyObject* args, char* format, ...)
把Python的数据类型解析为C的类型,这样C程序中才可以使用Python里面的数据


PyObject* Py_BuildValue(char *format, ...)
和PyArg_Parse刚好相反,构成一个参数列表,把C类型对象转化为Python对象,使得Python里面可以使用C类型数据


PyObject* PyObject_GetAttrString(PyObject *o, char* attr_name)
返回模块对象o中的attr_name属性或函数,相当于Python中表达式语句,o.attr_name。


PyObject* PyEval_CallObject(PyObject* pfunc, PyObject* pargs)
此处有两个参数,而且都是Python对象指针,其中pfunc是要调用的Python函数,一般来说可以使用Pyobject_GetAttrString()获得,pargs是函数的参数列表,通常是使用Py_BuildValue()来构建。


三:代码

下面来一份测试的:

Python代码:

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 


C++代码:

#include <Python.h>
#include <iostream>

int main()
{
	Py_Initialize();      
	if(!Py_IsInitialized())   //如果初始化失败,返回-1
		return -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");
		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'");
		return -1;
	}

	//生成参数
	pArgs = PyTuple_New(2);
	
	//s 代表字符串, i 代表整形变量, f 代表浮点数,o 代表一个python对象
	PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 3));   //i means integer
	PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 4));

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

	
	//调用另一个函数
	pFunc = PyDict_GetItemString(pDict, "foo");
	if(!pFunc || !PyCallable_Check(pFunc)){
		printf("can't find function 'pow'");
		return -1;
	}

	pArgs = PyTuple_New(1);
	PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 2));
	PyObject_CallObject(pFunc, pArgs);

	//减少引用计数
	Py_DECREF(pName);
	Py_DECREF(pArgs);
	Py_DECREF(pModule);
	
	//关闭解释器
	Py_Finalize();

	return 0;
}


输出如图:




其实这个时候我们可以修改修改pytest文件中的内容,发现不用重新编译,程序就能按照我们更新后的方式运行。这就是Python的好处,具有解释性!

参考:http://www.51cto.com/specbook/17/3604.htm

           http://blog.csdn.net/magictong/article/details/8947892

           http://blog.csdn.net/chinazhd/article/details/7268887

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值