您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 经营企划 > Python与C集成方法的初探
一、软件安装1、Python-2.3.3.exe(注意:版本有关系,有些高版本有问题)2、VC6.0二、运行环境配置1、本文默认Python的安装目录为:C:/Python23;在VCIDE中Tools-Options-Directories配置Includefiles为:C:/Python23/include;Libraryfiles为:C:/Python23/libs;2、如需要Debug版本的要下载python23_d.lib和python23_d.dll这两个文件,也可以下载Python源码来编译获得,具体可查阅相应文档。三、C调用Python1、Test.c源码intmain(intargc,char**argv){//初始化Python//在使用Python系统前,必须使用Py_Initialize对其//进行初始化。它会载入Python的内建模块并添加系统路//径到模块搜索路径中。这个函数没有返回值,检查系统//是否初始化成功需要使用Py_IsInitialized。PyObject*pName,*pModule,*pDict,*pFunc,*pArgs;Py_Initialize();//检查初始化是否成功if(!Py_IsInitialized()){return-1;}//添加当前路径//把输入的字符串作为Python代码直接运行,返回0//表示成功,-1表示有错。大多时候错误都是因为字符串//中有语法错误。PyRun_SimpleString(importsys);PyRun_SimpleString(sys.path.append('./'));//载入名为pytest的脚本pName=PyString_FromString(pytest);pModule=PyImport_Import(pName);if(!pModule){printf(can'tfindpytest.py);getchar();return-1;}pDict=PyModule_GetDict(pModule);if(!pDict){return-1;}//找出函数名为add的函数pFunc=PyDict_GetItemString(pDict,vcadd);if(!pFunc||!PyCallable_Check(pFunc)){printf(can'tfindfunction[vcadd]);getchar();return-1;}//参数进栈*pArgs;pArgs=PyTuple_New(2);//PyObject*Py_BuildValue(char*format,...)//把C++的变量转换成一个Python对象。当需要从//C++传递变量到Python时,就会使用这个函数。此函数//有点类似C的printf,但格式不同。常用的格式有//s表示字符串,//i表示整型变量,//f表示浮点数,//O表示一个Python对象。PyTuple_SetItem(pArgs,0,Py_BuildValue(l,3));PyTuple_SetItem(pArgs,1,Py_BuildValue(l,4));//调用Python函数PyObject_CallObject(pFunc,pArgs);//下面这段是查找函数foo并执行foopFunc=PyDict_GetItemString(pDict,vcfoo);if(!pFunc||!PyCallable_Check(pFunc)){printf(can'tfindfunction[vcfoo]);getchar();return-1;}pArgs=PyTuple_New(1);PyTuple_SetItem(pArgs,0,Py_BuildValue(l,2));//PyObject_CallObject(pFunc,pArgs);Py_DECREF(pName);Py_DECREF(pArgs);Py_DECREF(pModule);//关闭PythonPy_Finalize();return0;}2、pytest.py源码defadd(a,b):printinpythonfunctionaddprinta=+str(a)printb=+str(b)printret=+str(a+b)return3、运行设置将pytest.py文件与C工程编译的exe文件存放同一目录下(具体的存放路径应该可以统一配置,在此不便描述),启动编译的exe文件后即可调用pytest.py文件的函数及执行结果。四、Python调用C1、建立一个目录,整个目录名中不要包含中文。在目录下建立add.c,内容如下:#includePython.h;staticPyObject*add(PyObject*self,PyObject*args);//一定声明为static,把他们限制在这个文件范围里。几乎所有的参数都是PyObject类型。在python,每个东西都是object。staticPyObject*add(PyObject*self,PyObject*args){intx=0;inty=0;intz=0;if(!PyArg_ParseTuple(args,i|i,&x,&y))returnNULL;/*第一个参数是self,这个是python用的,每个函数都要有。我们暂时不管。args是一个参数列表。她把所有的参数都整合成一个string。所以我们需要从这个string里来解析我们的参数。PyArg_ParseTuple来完成这个任务。第一个参数是args,就是我们要转换的参数。第二个是格式符号。“s”代表是个string。从args里提取一个参数就写s,两个的话就写s|s,如果是一个string,一个int,就写s|i,和printf差不多。第三个参数就是提取出来的参数放置的真正位置。必须传递这个参数的地址。对于add,他将提取两个参数。分别是x和y。*/z=x+y;returnPy_BuildValue(i,z);/*调用完之后我们需要返回结果。这个结果是c的type或者是我们自己定义的类型。必须把他转换成PyObject,让python认识。这个用Py_BuildValue来完成。他是PyArg_ParseTuple的逆过程。他的第一个参数和PyArg_ParseTuple的第二个参数一样,是个格式化符号。第三个参数是我们需要转换的参数。Py_BuildValue会把所有的返回只组装成一个tutple给python。*/}staticPyMethodDefaddMethods[]={{add,add,METH_VARARGS,Executeashellcommand.},{NULL,NULL,0,NULL}}/*这个是一个c的结构。他来完成一个映射。我们需要把我们扩展的函数都映射到这个表里。表的第一个字段是python真正认识的。是python里的方法名字。第二个字段是python里的这个方法名字的具体实现的函数名。在python里调用add,真正执行的是用c写的add函数。第三个字段是METH_VARARGS,他告诉python,add是调用c函数来实现的。第四个字段是这个函数的说明。如果你在python里来help这个函数,将显示这个说明。相当于在python里的函数的文档说明。*/PyMODINIT_FUNCinitadd(){Py_InitModule(vince,addMethods);}/*注意,这个函数的名字不能改动。必须是init+模块名字。我们的模块名字是add。所以这个函数是initadd()。这样python在导入add的模块时候,才会找到这个函数,并调用。这个函数调用Py_InitModule来将模块名字和映射表结合在一起。他表示,add这个模块使用addMethods这个映射表。python应该这样导入我们的module的.*/然后建立setup.py这个文件,内容如下:#!/usr/bin/pythonfromdistutils.coreimportsetup,Extensionmodule1=Extension('add',sources=['add.c'])setup(name='PackageName',version='1.0',description='Thisisademopackage',ext_modules=[module1])在msdos下进入这个目录,输入命令setup.pybuild。如果你能编译成功,到你所在目录的build/lib.win32-2.3下会发现add.pyd文件,将文件复制到你所需要的地方(与python同目录下,放在其他目录的话要配置环境变量),启动python,然后:D:/c;pythonPython2.3.3(#51,Dec182003,20:22:39)[MSCv.120032bit(Intel)]onwin32Typehelp,copyright,creditsorlicenseformoreinformation.;;;importadd;;;printdir(add)['__doc__','__file__','__name__','add'];;;add.add(1,2)3;;;2、C源码staticPyObject*add(PyObject*self,PyObject*args){intx=0;inty=0;intz=0;if(!PyArg_ParseTuple(args,i|i,&x,&y))returnNULL;z=x+y;returnPy_BuildValue(i,z);}staticPyMethodDefaddMethods[]={{add,add,METH_VARARGS,Executeashellcommand,CreatebyVince.},{NULL,NULL,0,NULL}}PyMODINIT_FUNCinitvince(){Py_InitModule(vince,addMethods);}3、setup.py#!/usr/bin/pythonfromdistutils.coreimportsetup,Extensionmodule1=Extension('vince',sources=['Test.c'])setup(name='PackageName',version='1.0',description='Thisisademopackage',ext_modules=[module1])
本文标题:Python与C集成方法的初探
链接地址:https://www.777doc.com/doc-4991957 .html