c和python混合编程
Ⅰ python怎样嵌入c
用c语言编写一个动态库,提供两个函数,两个数的整形求和,两个浮点数的求和。取名为mylib.c。
将c函数文件编译成so动态库。运行gcc mylib.c -fPIC -shared -o libtest.so命令,在目录下可以看到生成的库文件libtest.so。
Python调用so库文件。首先导入ctypes,其次用CDLL加载so文件,最后调用对应的函数。将python代码保存到pydemo.py中。
执行python pydemo.py查看运行结果。
众多python培训视频,尽在python学习网,欢迎在线学习!
Ⅱ 怎样让Python脚本与C++程序互相调用
二、Python调用C/C++
1、Python调用C动态链接库
Python调用C库比较简单,不经过任何封装打包成so,再使用python的ctypes调用即可。
(1)C语言文件:pycall.c
[html] view plain
/***gcc -o libpycall.so -shared -fPIC pycall.c*/
#include <stdio.h>
#include <stdlib.h>
int foo(int a, int b)
{
printf("you input %d and %d\n", a, b);
return a+b;
}
(2)gcc编译生成动态库libpycall.so:gcc -o libpycall.so -shared -fPIC pycall.c。使用g++编译生成C动态库的代码中的函数或者方法时,需要使用extern "C"来进行编译。
(3)Python调用动态库的文件:pycall.py
[html] view plain
import ctypes
ll = ctypes.cdll.LoadLibrary
lib = ll("./libpycall.so")
lib.foo(1, 3)
print '***finish***'
(4)运行结果:
2、Python调用C++(类)动态链接库
需要extern "C"来辅助,也就是说还是只能调用C函数,不能直接调用方法,但是能解析C++方法。不是用extern "C",构建后的动态链接库没有这些函数的符号表。
(1)C++类文件:pycallclass.cpp
[html] view plain
#include <iostream>
using namespace std;
class TestLib
{
public:
void display();
void display(int a);
};
void TestLib::display() {
cout<<"First display"<<endl;
}
void TestLib::display(int a) {
cout<<"Second display:"<<a<<endl;
}
extern "C" {
TestLib obj;
void display() {
obj.display();
}
void display_int() {
obj.display(2);
}
}
(2)g++编译生成动态库libpycall.so:g++ -o libpycallclass.so -shared -fPIC pycallclass.cpp。
(3)Python调用动态库的文件:pycallclass.py
[html] view plain
import ctypes
so = ctypes.cdll.LoadLibrary
lib = so("./libpycallclass.so")
print 'display()'
lib.display()
print 'display(100)'
lib.display_int(100)
(4)运行结果:
3、Python调用C/C++可执行程序
(1)C/C++程序:main.cpp
[html] view plain
#include <iostream>
using namespace std;
int test()
{
int a = 10, b = 5;
return a+b;
}
int main()
{
cout<<"---begin---"<<endl;
int num = test();
cout<<"num="<<num<<endl;
cout<<"---end---"<<endl;
}
(2)编译成二进制可执行文件:g++ -o testmain main.cpp。
(3)Python调用程序:main.py
[html] view plain
import commands
import os
main = "./testmain"
if os.path.exists(main):
rc, out = commands.getstatusoutput(main)
print 'rc = %d, \nout = %s' % (rc, out)
print '*'*10
f = os.popen(main)
data = f.readlines()
f.close()
print data
print '*'*10
os.system(main)
(4)运行结果:
4、扩展Python(C++为Python编写扩展模块)
所有能被整合或导入到其它python脚本的代码,都可以被称为扩展。可以用Python来写扩展,也可以用C和C++之类的编译型的语言来写扩展。Python在设计之初就考虑到要让模块的导入机制足够抽象。抽象到让使用模块的代码无法了解到模块的具体实现细节。Python的可扩展性具有的优点:方便为语言增加新功能、具有可定制性、代码可以实现复用等。
为 Python 创建扩展需要三个主要的步骤:创建应用程序代码、利用样板来包装代码和编译与测试。
(1)创建应用程序代码
[html] view plain
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int fac(int n)
{
if (n < 2) return(1); /* 0! == 1! == 1 */
return (n)*fac(n-1); /* n! == n*(n-1)! */
}
char *reverse(char *s)
{
register char t, /* tmp */
*p = s, /* fwd */
*q = (s + (strlen(s) - 1)); /* bwd */
while (p < q) /* if p < q */
{
t = *p; /* swap & move ptrs */
*p++ = *q;
*q-- = t;
}
return(s);
}
int main()
{
char s[BUFSIZ];
printf("4! == %d\n", fac(4));
printf("8! == %d\n", fac(8));
printf("12! == %d\n", fac(12));
strcpy(s, "abcdef");
printf("reversing 'abcdef', we get '%s'\n", \
reverse(s));
strcpy(s, "madam");
printf("reversing 'madam', we get '%s'\n", \
reverse(s));
return 0;
}
上述代码中有两个函数,一个是递归求阶乘的函数fac();另一个reverse()函数实现了一个简单的字符串反转算法,其主要目的是修改传入的字符串,使其内容完全反转,但不需要申请内存后反着复制的方法。
(2)用样板来包装代码
接口的代码被称为“样板”代码,它是应用程序代码与Python解释器之间进行交互所必不可少的一部分。样板主要分为4步:a、包含Python的头文件;b、为每个模块的每一个函数增加一个型如PyObject* Mole_func()的包装函数;c、为每个模块增加一个型如PyMethodDef MoleMethods[]的数组;d、增加模块初始化函数void initMole()。
Ⅲ 求助 关于c程序中嵌入Python的问题
嵌入
与python的扩展相对,嵌入是把Python解释器包装到C的程序中。这样做可以给大型的,单一的,要求严格的,私有的并且(或者)极其重要的应用程序内嵌Python解释器的能力。一旦内嵌了Python,世界完全不一样了。
C调用python中的函数:
hw.py:
#coding=utf8
def hw_hs(canshu):
return canshu
if __name__ == "__main__":
ccss = "I am hw"
print hw_hs(ccss)
helloWorld.py:
#coding=utf8
import hw
def hello():
ccss = "I am helloWorld"
return hw.hw_hs(ccss)
if __name__ == "__main__":
print hello()
testcpypy.c:
//#include "testcpypy.h"
#include <Python.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
//初始化Python
Py_Initialize();
if (!Py_IsInitialized()) {
printf("Py_Initialize");
getchar();
return -1;
}
//执行python语句
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject *pMole = NULL;
PyObject *pFunc = NULL;
PyObject *reslt =NULL;
//载入python模块
if(!(pMole = PyImport_ImportMole("helloWorld"))) {
printf("PyImport_ImportMole");
getchar();
return -1;
}
//查找函数
pFunc = PyObject_GetAttrString(pMole, "hello");
if ( !pFunc || !PyCallable_Check(pFunc) )
{
printf("can't find function [hello]");
getchar();
return -1;
}
//调用python中的函数
reslt = (PyObject*)PyEval_CallObject(pFunc, NULL);
//printf("function return value : %d\r\n", PyInt_AsLong(reslt));
//将python返回的对象转换为C的字符串
char *resltc=NULL;
int res;
res = PyArg_Parse(reslt, "s", &resltc);
if (!res) {
printf("PyArg_Parse");
getchar();
return -1;
}
printf("resltc is %s", resltc);
getchar();
//释放内存
Py_DECREF(reslt);
Py_DECREF(pFunc);
Py_DECREF(pMole);
//关闭python
Py_Finalize();
return 0;
}
编译:
gcc -o testcpypy testcpypy.c -IC:\Python27\include -LC:\Python27\libs -lpython27 ---C:\Python27为python安装目录
或:
gcc -c testcpypy.c -IC:\Python27\include
gcc -o testcpypy.exe testcpypy.o -LC:\Python27\libs -lpython27
执行结果:
带参数的情况:
#include "callpydll.h"
#include "Python.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
int callhello(char *instr, char *outstr)
{
PyObject *pMole = NULL;
PyObject *pFunc = NULL;
PyObject *reslt = NULL;
PyObject *pParm = NULL;
char *resltc = NULL;
int resltn;
int res;
char *helloWorld = "TestIM_ProtocBuf";
char *im_account = "aaaa";
char *auth_code = "aaaa";
char *im_uid = "aaaa";
char *proxy_topic = "";
//初始化Python
Py_Initialize();
if (!Py_IsInitialized()) {
printf("Py_Initialize");
getchar();
return -1;
}
//执行python语句
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
//载入python模块
if(!(pMole = PyImport_ImportMole(helloWorld))) {
printf("PyImport_ImportMole");
getchar();
return -2;
}
//查找函数
pFunc = PyObject_GetAttrString(pMole, "login_proxy_body_serialize");
if ( !pFunc || !PyCallable_Check(pFunc) )
{
printf("can't find function [hello]");
getchar();
return -3;
}
//参数转换C --> python, 参数必须是元组(一个参数也是,否则会失败!!!坑啊)
pParm = Py_BuildValue("(ssss)", im_account, auth_code, im_uid, proxy_topic);
//调用python中的函数
reslt = (PyObject*)PyEval_CallObject(pFunc, pParm);
//将python返回的对象转换为C的字符串
res = PyArg_ParseTuple(reslt, "si", &resltc, &resltn);
if (!res) {
printf("PyArg_Parse");
getchar();
return -4;
}
printf("resltn is %d", resltn);
memcpy(outstr, resltc, strlen(resltc)+1);
//释放内存
Py_DECREF(reslt);
Py_DECREF(pFunc);
Py_DECREF(pMole);
Py_DECREF(pParm);
//关闭python
Py_Finalize();
return 0;
}
int main() {
int i;
char *dais = "iammain";
char res[10240];
memset(res,'\0',sizeof(res));
i = callhello(dais, res);
if(0 != i) {
printf("Notify:error");
getchar();
return -1;
}
printf("result is %s", res);
getchar();
return 0;
}
Ⅳ 怎样把Python代码嵌入到C程序
这篇文章主要介绍了将Python代码嵌入C++程序进行编写的实例,尽管通常还是Python代码中调用C++程序的情况较多...需要的朋友可以参考下
把python嵌入的C++里面需要做一些步骤
安装python程序,这样才能使用python的头文件和库
在我们写的源文件中增加“Python.h”头文件,并且链入“python**.lib”库(还没搞清楚这个库时静态库还是导出库,需要搞清楚)
掌握和了解一些python的C语言api,以便在我们的c++程序中使用
常用的一些C API函数
在了解下面的函数之前有必要了解一下**PyObject***指针,python里面几乎所有的对象都是使用这个指针来指示的。
Py_Initialize()&&Py_Finalize()
在调用任何python的c函数之前需要调用的函数,“Py_Initialize”是用来初始化python模块的,推测是加载初始化加载dll的。对应的在使用python模块之后用“Py_Finalize”来释放模块。
PyImport_ImportMole()
用来载入一个python模块,这个模块就是一般的python文件。这里需要注意的是,在加载这个模块的时候会执行模块里面所有可以执行的语句。包括import导入语句和在函数体之外的所有语句
PyObject_GetAttrString()
返回模块里面的函数
Py_BuildValue()
建立一个参数元组,一般都是用这个函数来建立元组,然后将这个元组作为参数传递给python里面的函数。
PyEval_CallObject()
调用函数,并把“Py_BuildValue”建立的元组作为参数传递给被调用的函数
源码实例
下面的实例是在c++代码中调用Python的函数,传递参数并且获取返回值
test.cpp代码
[cpp]view plain
#include<iostream>
#include<Python.h>
usingnamespacestd;
intmain(intargc,char*argv[])
{
Py_Initialize();//初始化
PyObject*pMole=NULL;
PyObject*pFunc=NULL;
PyObject*pParam=NULL;
PyObject*pResult=NULL;
constchar*pBuffer=NULL;
intiBufferSize=0;
pMole=PyImport_ImportMole(“test_python");
if(!pMole)
{
cout<<"getmolefailed!"<<endl;
exit(0);
}
pFunc=PyObject_GetAttrString(pMole,"main");
if(!pFunc)
{
cout<<"getfuncfailed!"<<endl;
cout<<int(pFunc)<<endl;
exit(0);
}
pParam=Py_BuildValue("(s)","HEHEHE");
pResult=PyEval_CallObject(pFunc,pParam);
if(pResult)
{
if(PyArg_Parse(pResult,"(si)",&pBuffer,iBufferSize))
{
cout<<pBuffer<<endl;
cout<<iBufferSize<<endl;
}
}
Py_DECREF(pParam);
Py_DECREF(pFunc);
Py_Finalize();
//cout<<"hello"<<endl;
return0;
}
defmain(szString):
return("hello",5)
test_python.py代码
[py]view plain
Ⅳ 请教高手,我在C/C++中嵌入python,用PyImport
#include<iostream>
#include<Python.h>
usingnamespacestd;
voidHelloWorld();
voidAdd();
voidTestTransferDict();
voidTestClass();
intmain()
{
cout<<"StartingTest..."<<endl;
cout<<"HelloWorld()-------------"<<endl;
HelloWorld();
cout<<"Add()--------------------"<<endl;
Add();
cout<<"TestDict-----------------"<<endl;
TestTransferDict();
cout<<"TestClass----------------"<<endl;
TestClass();
system("pause");
return0;
}
//调用输出"HelloWorld"函数
voidHelloWorld()
{
Py_Initialize();//使用python之前,要调用Py_Initialize();这个函数进行初始化
PyObject*pMole=NULL;//声明变量
PyObject*pFunc=NULL;//声明变量
pMole=PyImport_ImportMole("Test001");//这里是要调用的Python文件名
pFunc=PyObject_GetAttrString(pMole,"HelloWorld");//这里是要调用的函数名
PyEval_CallObject(pFunc,NULL);//调用函数,NULL表示参数为空
Py_Finalize();//调用Py_Finalize,这个和Py_Initialize相对应的.
}
//调用Add函数,传两个int型参数
voidAdd()
{
Py_Initialize();
PyObject*pMole=NULL;
PyObject*pFunc=NULL;
pMole=PyImport_ImportMole("Test001");//Test001:Python文件名
pFunc=PyObject_GetAttrString(pMole,"add");//Add:Python文件中的函数名
//创建参数:
PyObject*pArgs=PyTuple_New(2);//函数调用的参数传递均是以元组的形式打包的,2表示参数个数
PyTuple_SetItem(pArgs,0,Py_BuildValue("i",5));//0---序号i表示创建int型变量
PyTuple_SetItem(pArgs,1,Py_BuildValue("i",7));//1---序号
//返回值
PyObject*pReturn=NULL;
pReturn=PyEval_CallObject(pFunc,pArgs);//调用函数
//将返回值转换为int类型
intresult;
PyArg_Parse(pReturn,"i",&result);//i表示转换成int型变量
cout<<"5+7="<<result<<endl;
Py_Finalize();
}
//参数传递的类型为字典
voidTestTransferDict()
{
Py_Initialize();
PyObject*pMole=NULL;
PyObject*pFunc=NULL;
pMole=PyImport_ImportMole("Test001");//Test001:Python文件名
pFunc=PyObject_GetAttrString(pMole,"TestDict");//Add:Python文件中的函数名
//创建参数:
PyObject*pArgs=PyTuple_New(1);
PyObject*pDict=PyDict_New();//创建字典类型变量
PyDict_SetItemString(pDict,"Name",Py_BuildValue("s","WangYao"));//往字典类型变量中填充数据
PyDict_SetItemString(pDict,"Age",Py_BuildValue("i",25));//往字典类型变量中填充数据
PyTuple_SetItem(pArgs,0,pDict);//0---序号将字典类型变量添加到参数元组中
//返回值
PyObject*pReturn=NULL;
pReturn=PyEval_CallObject(pFunc,pArgs);//调用函数
//处理返回值:
intsize=PyDict_Size(pReturn);
cout<<"返回字典的大小为:"<<size<<endl;
PyObject*pNewAge=PyDict_GetItemString(pReturn,"Age");
intnewAge;
PyArg_Parse(pNewAge,"i",&newAge);
cout<<"TrueAge:"<<newAge<<endl;
Py_Finalize();
}
//测试类
voidTestClass()
{
Py_Initialize();
PyObject*pMole=NULL;
PyObject*pFunc=NULL;
pMole=PyImport_ImportMole("Test001");//Test001:Python文件名
pFunc=PyObject_GetAttrString(pMole,"TestDict");//Add:Python文件中的函数名
//获取Person类
PyObject*pClassPerson=PyObject_GetAttrString(pMole,"Person");
//创建Person类的实例
PyObject*pInstancePerson=PyInstance_New(pClassPerson,NULL,NULL);
//调用方法
PyObject_CallMethod(pInstancePerson,"greet","s","HelloKitty");//s表示传递的是字符串,值为"HelloKitty"
Py_Finalize();
}
#test.py
defHelloWorld():
print"HelloWorld"
defadd(a,b):
returna+b
defTestDict(dict):
printdict
dict["Age"]=17
returndict
classPerson:
defgreet(self,greetStr):
printgreetStr
#printadd(5,7)
#a=raw_input("EnterToContinue...")
结果:
注意两点:
若编译Debug版,请将C:/Python26/libs下的python26.lib复制一份改名为python26_d.lib
test.py 记得放项目的当前目录。
测试通过
Ⅵ 怎样把Python代码嵌入到C程序
步骤1:安装Python开发包
由于需要访问Python/C API,首先安装Python开发包。
在Debian,Ubuntu或Linux Mint中:
在CentOS,Fedora或RHEL中:
安装成功后,Python头文件在/usr/include/python2.7。根据Linux发行版的不同,确切的路径可能是不相同的。例如,CentOS 6中是/usr/include/python2.6。
步骤2:初始化解释器并设置路径
C中嵌入Python的第一步是初始化Python解释器,这可以用以下C函数完成。
初始化解释器后,需要设置你的C程序中要导入的Python模块的路径。例如,比如你的Python模块位于/usr/local/moles。然后使用以下C函数调用来设置路径。
步骤3:数据转换
C中嵌入Python最重要的方面之一是数据转换。从C中传递数据到Python函数,需要首先将数据从C数据类型转换到Python数据类型。Python/C API提供各种函数来实现这。例如,转换C字符串到Python字符串,使用PyString_FromString函数。
另外一个类似函数PyInt_FromLong,将C中long数据类型转换为Python int。每个Python/C API函数返回一个PyObject类型的引用。
步骤4:定义一个Python模块
当你想嵌入Python代码到另一种语言如C,该代码需要被写成Python模块,然后用另一种语言“导入”。所以让我们来看看如何在C中导入Python模块。
为了进行说明,我们实现一个简单的Python模块例子如下:
以上的Python函数有一个字符串作为参数并返回两个重复的字符串。例如,如果输入字符串是“cyberpersons”,该函数返回'cyberpersonscyberpersons'。此模块文件命名为“printData.py”并将它放在前面声明的Python模块目录中(/usr/local/moles)。
步骤5:加载一个Python模块
现在你已经定义了Python模块,是时候在C程序中加载它了。导入模块的C代码看起来像这样:
步骤6:构建函数的参数
当加载一个模块时,可以调用模块中定义的Python函数。通常,我们需要传递一个或多个参数到一个Python函数。我们必须构建一个Python元组对象,它包括Python函数中的参数。
在我们的例子中,printData函数定义带一个参数的模块。因此,我们构建一个大小是一的Python元组对象如下。我们可以使用PyTuple_SetItem设置元组对象的每个项。
我们已经成功构建一个参数传递到函数调用,是时候从C程序调用python函数了。
步骤7:调用Python函数
一旦成功创建Python元组对象作为函数参数,我们可以调用一个带参数的Python函数。为此,通过使用PyObject_GetAttrString首先获得模块中定义的函数的引用,然后使用PyObject_CallObject调用该函数。例如:
步骤8:错误检查
避免运行时错误的常见方法是检查函数的返回值并根据返回值采取适当的行动。类似于C程序中的全局变量errno,Python/C API提供一个全局指示符,它报告最后发生的错误。当Python/C API函数失败,全局指示符设置为指示错误,并且PyErr_Print可以用于显示相应的人类可读的trackback。例如:
在你的应用程序中,你可以轻松地将各种错误检查。
这里是完整的C程序,它如本教程描述的嵌入Python代码。
步骤9:编译和执行
保存以上代码到finalCode.c,并且链接Python库(-lpython2.7)编译该代码。根据发行版的不同,可能使用不同的版本(例如,-lpython2.6)。
Ⅶ python与c++混合编程如何入门
派桑和c/c++实际上是不同的工具,一个是斧头,一个是菜刀,各有各的用途。非要把让菜刀能砍柴,让斧头能切菜,这种努力有无必要,值得考虑。
派桑常用剧本,噜苏,速度慢,不严谨,但有它的便利,例如它有 list, tuple, 之类的东西。
混合编程 常用于 提高 派桑 速度。
常用 方法 是(1)包含 Python.h 文件头 (2)定义 派桑 的 各种对象 为 各种 c 结构
(3)派桑 的 各种对象用指针,名字用 Py 或 _Py大头 动态分配 在 heap (4)用函数跟踪统计 各种对象结构 的个数变化,即时 释放内存(5)及时处理 派桑 exception
(6) 输出为派桑的数据格式。
我没有合起来用过,不过基本套路如此。
Ⅷ 求助 关于c程序中嵌入Python的问题
在C/C++中嵌入Python也比较简单,首先需要在VC中添加Python的include文件目录和lib文件目录:
VC6.0下,打开 tools->options->directories->show directories for,将Python安装目录下的inlude目录添加到inlude files项中,将libs目录添加到library files项中。
VC2005下,打开tools->options->项目和解决方案->VC++目录,然后做相同工作。
代码如下:
//在debug下执行出错,“无法找到python31_d.lib文件”,后查到原因是:在debug下生成必须要有python31_d.lib文件,否则只能在release下生成
#include <python.h>
int main()
{
Py_Initialize();
PyRun_SimpleString("Print 'hi, python!'");
Py_Finalize();
return 0;
}
Py_Initialize函数原型是:void Py_Initialize(),在嵌入Python脚本时必须使用该函数,它初始化Python解释器,在使用其他的Python/C API之前必须先调用该函数。可以使用Py_IsInitialized函数判断是否初始化成功,成功返回True。
PyRun_SimpleString函数原型是int PyRun_SimpleString(const char *command),用来执行一段Python代码。注意:是否需要维持语句间的缩进呢?
Py_Finalize函数原型是void Py_Finalize(),用于关闭Python解释器,释放解释器所占用的资源。
PyRun_SimpleFile函数可以用来运行".py"脚本文件,函数原型如下:
int PyRun_SimpleFile(FILE *fp, const char *filename);
其 中fp是打开的文件指针,filename是要运行的python脚本文件名。但是由于该函数官方发布的是由visual studio 2003.NET编译的,如果使用其他版本的编译器,FILE定义可能由于版本原因导致崩溃。同时,为简便起见可以使用如下方式来代替该函数:
PyRun_SimpleString("execfile(‘file.py’)"); //使用execfile来运行python文件
Py_BuildValue()用于对数字和字符串进行转换处理,变成Python中相应的数据类型(在C语言中,所有Python类型都被声明为PyObject类型),函数原型如下:
PyObject *Py_BuildValue(const char *format, …..);
PyString_String()用于将PyObject*类型的变量转换成C语言可以处理的char*型,具体原型如下:
char* PyString_String(PyObject *p);
列表操作函数:
PyObject * PyList_New(Py_ssize_t len);
int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item);
PyObject * PyList_GetItem(PyObject *list, Py_ssize_t index);
int PyList_Append(PyObject *list, PyObject *item);
int PyList_Sort(PyObject *list);
int PyList_Reverse(PyObject *list);
Py_ssize_t PyList_Size(PyObject *list);
元组操作函数:
int PyTuple_New(Py_ssize_t len);
int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o);
PyObject * PyTuple_GetItem(PyObject *p, Py_ssize_t pos);
int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize); //注意是**指针
字典操作函数:
PyObject * PyDict_New();
int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val);
int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val);
PyObject* PyDict_GetItem(PyObject *p, PyObject *key);
PyObject* PyDict_GetItemString(PyObject *p, const char *key);
//与PyDict_SetItemString对应
int PyDict_DelItem(PyObject *p, PyObject *key);
int PyDict_DelItemString(PyObject *p, char *key);
//与PyDict_SetItemString对应
int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue);
PyObject* PyDict_Items(PyObject *p);
PyObject* PyDict_keys(PyObject *p);
PyObject* PyDict_Values(PyObject *p);
在C/C++中使用Python对象应正确地处理引用计数问题,否则容易导致内存泄漏。当使用Python/C API中的函数创建列表、元组、字典等后,在对其完成操作后应该使用Py_CLEAR()和Py_DECREF()等宏来销毁这些对象。原型如下:
void Py_CLEAR(PyObject *o);
void Py_DECREF(PyObject *o);
其中,对于Py_CLEAR函数,参数可以为NULL指针,表示不进行任何操作,但是Py_DECREF函数不能为NULL指针,否则导致错误。
使用PyImport_Import()函数可以在C中导入Python模块,返回一个模块对象。函数原型为:
PyObject* PyImport_Import(PyObject *name);
PyMole_GetDict()函数可以获得Python模块中的函数列表,返回一个字典,字典中的关键字为函数名,值为函数的调用地址。原型如下:
PyObject* PyMole_GetDict(PyObject *mole);
使用PyObject_CallObject()函数和PyObject_CallFunction()函数可以在C中调用Python中的函数,原型如下:
PyObject* PyObject_CallObject(PyObject *callable_object, PyObject *args);
//args是元组形式
PyObject* PyObject_CallFunction(PyObject *callable, char *format, ……);
//format是类似”iss”这样的参数类型,后面是指定参数
可以使用PyCallable_Check(func)来判断是否可以调用函数,可以则返回True。