您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 能源与动力工程 > c语言编写python模块
本文档主要介绍如何使用VS2010来把c语言编写好的函数编译成python模块1.准备1.1主要工具笔者的主要工具有:python-2.7.6.amd64,即64位的python,当然,32位的也可以,可到下载,本人用的是python2.7,用python3.x估计也没有问题,我未用过.VS2010,这个不用解释了吧。c语言的编译器必须要有的,VS的版本可以随意选择,不过貌似python对VS2010不是特别的支持,支持得比较好的是VS2008。后面会介绍使用VS2010遇到的问题,当然最后得到了解决。说实话,VS2010也不算新的了,python都2.7了还不支持,真坑爹。swigwin-3.0.0,这是个好用的小工具,可以非常方便地把我们非常自然的c语言编写的函数进行转换,转换成可以编译成python模块的包装代码,可以说是中间工具了。可到,Windows用户应该下载swigwin-3.0.0。1.2设置环境变量必须设置python和swig的环境变量,本人python的安装目录为D:\python\Python27,swig的解压目录为D:\swigwin-3.0.0,将其添加到path环境变量即可。注意:安装目录必须要按照自己的安装目录进行设置,后面的命令也要用到安装目录,因此这里提醒一下。2.编写c语言代码并生成Python模块2.1使用swig生成包装代码并编译编写c语言函数这里笔者使用《Python基础教程(第二版)》中的回文函数例子。先编写好两个文件:palindrome.c与palindrome.i程序(这是自己编写的c语言函数):#includestring.hintis_palindrome(char*text){inti,n=strlen(text);for(i=0;i=n/2;++i){if(text[i]!=text[n-i-1])return0;}return1;}代码:%modulepalindrome%{#includestring.h%}externintis_palindrome(char*text);两个文件如图所示,本人把两个文件放在了D:\python\ceshi中palindrome2.c暂时先不用管它,等下会知道的。打开VisualStudiox64Win64命令提示(2010),32位的用VisualStudio命令提示(2010)进入palindrome.c与palindrome.i所在的文件夹(笔者的是D:\python\ceshi)输入以下命令swig-pythonpalindrome.icl/cpalindrome.ccl/ID:\python\Python27\include/cpalindrome_wrap.ccl/LDpalindrome.objpalindrome_wrap.obj/ID:\python\Python27\includeD:\python\Python27\libs\python27.lib/o_palindrome.pyd第一条命令swig-pythonpalindrome.i使用palindrome.i对palindrome.c进行转换会生成palindrome_wrap.c和palindrome.py两个文件,如图所示其中palindrome_wrap.c是重要的,这叫包装代码,其实假如自己直接写包装代码的话,那么前面就不用写palindrome.c,后面会介绍自己写包装代码而不靠swig。第二第三条命令cl/cpalindrome.ccl/ID:\python\Python27\include/cpalindrome_wrap.c其中/c是指编译但不链接,即只生成.obj文件,/I是指附加包含文件,注意严格区分大小写之后陆续生成两个文件,如图所示最后一条命令cl/LDpalindrome.objpalindrome_wrap.obj/ID:\python\Python27\includeD:\python\Python27\libs\python27.lib/o_palindrome.pyd/LD是指创建动态链接库,而/o则表示指定输出的文件名,注意,/o并不是标准的选项,可查阅(v=vs.100).aspx,因此执行后会出现警告”cl:命令行warningD9035:“o”选项已否决,并将在将来的版本中移除”,但是实际上也是会生成_palindrome.pyd的,因此/o选项还是可用的。实际上,/o非常有用,如果不用它的话,那么就只能调用链接器命令link,这就比较麻烦了,因此即使此选项已被否决,但能用的话还得用。最后生成_palindrome.pyd,如图所示实际上,如果没有/o_palindrome.pyd这一项,则会生成palindrome.dll,只是这里改了后缀名为.pyd,如果后缀是.dll的话,那么python将不能识别,.pyd是python在Windows中能识别的模块后缀,而在Linux中则是.so。注意,_palindrome前面的下划线_是非常有讲究的,它配合swig的生成规则,假如取其它名字的话,则模块不能导入成功。因此,假如不用/o_palindrome.pyd这一项的话,则必须手动把palindrome.dll改为_palindrome.pyd。将_palindrome.pyd文件复制到D:\python\Python27\Lib\site-packages中,这样的话python就可以调用该模块了注:写这一部分其实是有目的的,这是因为《Python基础教程》只给出了gcc的编译方法,而没有给出VS的编译方法,幸好网上查找到了于是再自己稍加摸索,找出了VS对应的步骤。《Python基础教程(第二版)》P298给出的gcc的命令是这样的gcc–cpalindrome.cgcc–I$PYTHON_HOME–I$PYTHON_HOME/Include–cpalindrome_wrap.cgcc–sharedpalindrome.opalindrome_wrap.o–o_palindrome.sogcc的-c对应cl的/c,都是编译但不链接的意思,–I对应/I,都是附加包含文件的意思,而-shared对应/LD,都是创建动态链接库的意思。而这里.o对应.obj,.so对应.pyd,都差不多,甚至选项的符号-在cl命令中也可以用,例如-c选项在cl命令中也是可以使用的。2.2自己编写包装代码这个笔者只是简短介绍,具体请查阅《Python基础教程(第二版)》,编写palindrome2.c(这个前面提到过)代码如下#includePython.hstaticPyObject*is_palindrome(PyObject*self,PyObject*args){inti,n;constchar*text;intresult;/*smeansasinglestring:*/if(!PyArg_ParseTuple(args,s,&text)){returnNULL;}/*Theoldcode,moreorless:*/n=strlen(text);result=1;for(i=0;i=n/2;++i){if(text[i]!=text[n-i-1]){result=0;break;}}/*imeansasingleinteger:*/returnPy_BuildValue(i,result);}/*Alistingofourmethods/functions:*/staticPyMethodDefPalindromeMethods[]={/*name,function,argumenttype,docstring*/{is_palindrome,is_palindrome,METH_VARARGS,Detectpalindromes},/*Anend-of-listingsentinel:*/{NULL,NULL,0,NULL}};/*Aninitializationfunctionforthemodule(thenameissignificant):*/PyMODINIT_FUNCinitpalindrome(){Py_InitModule(palindrome,PalindromeMethods);}其中里面指定了模块名为palindrome,因此输出的文件名也一定要为palindrome执行代码cl/LDpalindrome2.c/ID:\python\Python27\includeD:\python\Python27\libs\python27.lib/opalindrome.pyd就这么简单地搞定了。3.使用Distutils3.1自行写包装代码的情况前面使用这么多命令是不是晕了呢,的确,这样输命令非常不友好。不过不用怕,python提供了一个内置的工具Distutils来使用,只要再编写一个setup.py文件,再输入一条简单的命令,Distutils就可以帮你把编译,安装一手包办。这里先不用swig,用前面提到的palindrome2.c,然后编写setup.py文件,如图所示代码如下:fromdistutils.coreimportsetup,Extensionsetup(name='palindrome',version='1.0',ext_modules=[Extension('palindrome',['palindrome2.c'])])然后运行pythonsetup.pyinstall出现了错误!前面说了,python2.7对VS2010不是特别地支持,但对VS2008是支持的,因此假如安装了VS2008的话,那么不会有任何问题,但VS2010则会出现问题。解决方法是,输入SETVS90COMNTOOLS=%VS100COMNTOOLS%命令,硬性设置环境变量,为什么这样设置呢,具体可以参考然后再执行pythonsetup.pyinstall这次总算成功了,图中可以看到会有一些警告,不过可以安心地忽略它。并且,还能够知道Distutils具体的运行是怎样的,它实际上就是把前面的提到的手动编译的命令集成到里面去罢了,没什么神秘的。我们还可以注意到,Distutils还智能地复制了palindrome.pyd的副本到D:\python\Python27\Lib\site-packages里面,不用自己手动复制了,挺方便的,这其实是pythonsetup.pyinstall中的install决定的,假如命令是pythonsetup.pybuild的话,则不会把模块文件安装过去。3.2使用swig的情况假如使用swig的话,那么在命令行中使用的swig的命令也可以省去了,因为Distutils也会帮我们执行。把setup.py改成如图所示(这里使用《Python基础教程》(第二版)P310中的代码):注意,这里用的是palindrome.c,不是palindrome2.c了,并且因为要用swig,因此palindrome.i也是必须的。然后输入命令pythonsetup.pyinstall很不幸,出现了错误!无法解析的外部符号。为什么会这样呢,明明照着书本做的喔。想了想前面用的模块名,是_palindrome,已经说了此模块名是有讲究的,是为了配合swig的生成规则,那么改一下是不是就行呢?于是我对setup
本文标题:c语言编写python模块
链接地址:https://www.777doc.com/doc-4941423 .html