python定义函数调用接口_c++调用python函数接口

前两篇都是介绍Python调用C++的,换句话说,就是需要把C++封装成Python可以“理解”的类型。这篇,我打算说一下,C++怎么去调用Python脚本。其实这两者之间是相通的,就是需要可以互操作。按照惯例,先贴代码。

test.cpp

/*

* test.cpp

*  Created on: 2010-8-12

*      Author: lihaibo

*/

#include 

#include 

#include 

voidprintDict(PyObject* obj) {

if(!PyDict_Check(obj))

return;

PyObject *k, *keys;

keys = PyDict_Keys(obj);

for(inti = 0; i 

k = PyList_GET_ITEM(keys, i);

char* c_name = PyString_AsString(k);

printf("%s/n", c_name);

}

}

intmain() {

Py_Initialize();

if(!Py_IsInitialized())

return-1;

PyRun_SimpleString("import sys");

PyRun_SimpleString("sys.path.append('./')");

//导入模块

PyObject* pModule = PyImport_ImportModule("testpy");

if(!pModule) {

printf("Cant open python file!/n");

return-1;

}

//模块的字典列表

PyObject* pDict = PyModule_GetDict(pModule);

if(!pDict) {

printf("Cant find dictionary./n");

return-1;

}

//打印出来看一下

printDict(pDict);

//演示函数调用

PyObject* pFunHi = PyDict_GetItemString(pDict, "sayhi");

PyObject_CallFunction(pFunHi, "s","lhb");

Py_DECREF(pFunHi);

//演示构造一个Python对象,并调用Class的方法

//获取Second类

PyObject* pClassSecond = PyDict_GetItemString(pDict, "Second");

if(!pClassSecond) {

printf("Cant find second class./n");

return-1;

}

//获取Person类

PyObject* pClassPerson = PyDict_GetItemString(pDict, "Person");

if(!pClassPerson) {

printf("Cant find person class./n");

return-1;

}

//构造Second的实例

PyObject* pInstanceSecond = PyInstance_New(pClassSecond, NULL, NULL);

if(!pInstanceSecond) {

printf("Cant create second instance./n");

return-1;

}

//构造Person的实例

PyObject* pInstancePerson = PyInstance_New(pClassPerson, NULL, NULL);

if(!pInstancePerson) {

printf("Cant find person instance./n");

return-1;

}

//把person实例传入second的invoke方法

PyObject_CallMethod(pInstanceSecond, "invoke","O", pInstancePerson);

//释放

Py_DECREF(pInstanceSecond);

Py_DECREF(pInstancePerson);

Py_DECREF(pClassSecond);

Py_DECREF(pClassPerson);

Py_DECREF(pModule);

Py_Finalize();

return0;

}

编译

g++ test.cpp -o test -lpython2.6

testpy.py

#!/usr/bin/python

# Filename: test.py

classPerson:

defsayHi(self):

print'hi'

classSecond:

definvoke(self,obj):

obj.sayHi()

defsayhi(name):

print'hi',name;

执行

lhb@localhost:~/maplib/clib/pyc/invokepy$ ./test

sayhi

__builtins__

__file__

__package__

Person

Second

__name__

__doc__

hi lhb

hi

我简单解释一下

这个例子演示了,创建python中Person类的实例,并作为参数调用Second的方法。

Py_Initialize()和Py_Finalize()是初始和销毁Python解释器

PyRun_SimpleString("import sys")导入sys,接着设置py文件的路径PyRun_SimpleString("sys.path.append('./')")

导入模块PyImport_ImportModule("testpy"),就是testpy.py模块。

获取模块字典列表,PyModule_GetDict(pModule),可以打印出来看一下如voidprintDict(PyObject* obj)函数

从字典中获取类的类型PyDict_GetItemString(pDict,"Second"),如函数也是这样获取的

创造类的实例PyInstance_New(pClassSecond,NULL,NULL)

调用实例的方法PyObject_CallMethod(pInstanceSecond,"invoke","O",pInstancePerson)

整个流程就是这样的,并不复杂,如果要进一步研究可以参考:http://www.python.org/doc/

比较特殊的是调用Python函数时,参数的传递,就是c++的类型,怎么转换成Python的类型;另外一个问题是,Python函数的返回值,怎么转换成C++中的类型。

C++转换成Python类型,Py_BuildValue()

http://www.python.org/doc/1.5.2p2/ext/buildValue.html

PyObject* pArgs=PyTuple_New(1); //有几个参数,就是几

PyTuple_SetItem(pArgs,0,Py_BuildValue("i",3));  //初始第一个参数,数据类型是i,就是int,值是3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值