当前位置: 首页 > 科技观察

您是否尝试过混合使用C和Python进行编程?两者相加,还不是已经无敌了!

时间:2023-03-17 15:13:58 科技观察

C语言是编程语言的祖母,但随着一代又一代编程语言的成长,祖母们也会在沙滩上拍照。很多朋友应该学过或者了解过C语言,因为软件系会教我,但是我想很多人都没有学过Python。下面小编就为大家介绍一下,C语言和Python编程混合在一起,会擦出怎样的火花!MacOSX下的编译命令同上生成可执行文件后,直接运行,结果输出12HelloPython!Python库函数PyRun_SimpleString可以以字符串形式执行Python代码。这段代码虽然很简单,但是除了用C语言动态生成一些Python代码外,并没有什么用处。我们需要的是C语言的数据结构,能够和Python交互。让我们举个例子。比如有一天我们用Python写了一个特别强大的函数:从上面的代码,我们可以窥见Python内部是如何工作的:所有的Python元素,模块,函数,元组,字符串等等,其实都是PyObject。要在C语言中操作它们,请使用PyObject*。Python类型和C语言类型可以相互转换。将Python类型XXX转换为C语言类型YYY,使用PyXXXAsYYY函数;要将C类型YYY转换为Python类型XXX,请使用PyXXXFromYYY函数。也可以创建Python类型的变量,使用PyXXX_New创建XXX类型的变量。如果a是一个Tuple,那么a[i]=b对应的是PyTupleSetItem(a,i,b),有理由相信还有一个函数PyTupleGetItem可以获取某一项的值。不仅Python语言非常优雅,Python的库函数API也非常优雅。现在我们有了一个C语言的函数,我们可以编写一个main来测试它是如何使用本节开头使用的方法编译的。在Linux/MacOSX上运行这个例子之前,你可能需要设置环境变量:bash:12exportPYTHONPATH=.:$PYTHONPATHcsh:12setenvPYTHONPATH.:$PYTHONPATH2Python调用C/C++(Basic)这样的实践称为Python扩展。比如我们有一个强大的C函数除了强大的函数great_function之外,这个文件还有如下几个部分:包装函数greatfunction。它负责将Python参数转换为C参数(PyArgParseTuple),调用实际的greatfunction,并对great_function的返回值进行处理,最后返回给Python环境。导出表CreateModuleMethods。它负责告诉Python这个模块中哪些函数可以被Python调用。导出表的名称可以随意选择,每一项有4个参数:第一个参数是提供给Python环境的函数名,第二个参数是greatfunction,是包装函数。第三个参数的意思是参数变长,第四个参数是描述字符串。导出表总是以{NULL,NULL,0,NULL}结尾。导出函数initgreat_module。这个名字不是可选的,它是你的模块名加上前缀init。模块名称与导出函数中的导出表连接在一起。Windows下在VisualStudio命令提示符下编译这个文件的命令是这部分的参考资料《Python源码剖析-深度探索动态语言核心技术》是系统介绍CPython实现和运行原理的优秀教程。Python官方文档这一章详细介绍了C/C++与Python的双向交互。规范方式如下:3.BuildingCandC++Extensionswithdistutils__用作字典的官方参考文档Python/CAPIReferenceManual__有非Python关键字cdef和public。这些关键字属于Cython。由于我们需要在C语言中使用“编译过的Python代码”,所以我们必须让great_function对外可见,方法修饰为“public”。而cdef类似于Python的def,Cython的关键字public只能在使用cdef的时候使用。此函数的其余部分与普通Python代码相同。接下来,编译great_module.pyx。编译命令同***部分:Windows下的编译命令是在VisualStudio命令提示符下编译:12cl/LDdllmain.cgreat_module.c-IC:Python27includeC:Python27libspython27.lib会得到一个dllmain.dll。我们在Excel中使用,没错,就是传说中的Excel和Python混合编程:参考:Cython的官方文档,质量很高:接下来用SWIG将这个配置文件编译成所谓的PythonModuleWrapper12swig-pythonmymodule.i得到一个mymodule_wrap.c和一个mymodule.py。将其编译为Python扩展:Windows:12cl/LDmymodule_wrap.c/o_mymodule.pyd-IC:Python27includeC:Python27libspython27.libLinux:12gcc-fPIC-sharedmymodule_wrap.c-o_mymodule.so-I/usr/include/python2.7/-lpython2.7注意输出文件名前加了下划线。现在你可以在Python下立即使用这个模块:也就是说,SWIG自动完成了Python类型转换、模块初始化、导出码表生成等诸多工作。对于C++,SWIG也可以应付。比如下面的代码中有C++类的定义:写在***中:由于CPython本身结构设计合理,所以很容易扩展Python的C/C++。如果您想快速完成工作,Cython(C/C++调用Python)和SWIG(Python调用C/C++)是不错的选择。但是,一旦涉及到更复杂的转换任务,无论你继续使用Cython还是SWIG,你仍然需要学习Python源码。