C 语言是编程语言的祖母,但是随着一代一代的编程语言长大,所以祖母也是会拍在沙滩上的,很多小小伙伴应该都会学过或者了解 C 语言,因为软件系的会教嘛,但是
Python我想很多人都没学过,下面小编给大家介绍下,C 语言和
Python一起混合编程会产生什么不一样的火花吧!
1、C/C++ 调用 Python(基础篇) 在 Mac OS X 下的编译命令同上 产生可执行文件后,直接运行,结果为输出
Hello Python!
Python 库函数 PyRun_SimpleString 可以执行字符串形式的 Python 代码。
虽然非常简单,但这段代码除了能用 C 语言动态生成一些 Python 代码之外,并没有什么用处。我们需要的是 C 语言的数据结构能够和 Python 交互。
下面举个例子,比如说,有一天我们用 Python 写了一个功能特别强大的函数:
所有 Python 元素,module、function、tuple、string 等等,实际上都是 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/Mac OSX 运行此示例之前,可能先需要设置环境变量:
bash:
export PYTHONPATH=.:$PYTHONPATH
csh:
setenv PYTHONPATH.:$PYTHONPATH
2 Python 调用 C/C++(基础篇)
这种做法称为 Python 扩展。
比如说,我们有一个功能强大的 C 函数
包裹函数 greatfunction。它负责将 Python 的参数转化为 C 的参数 (PyArgParseTuple),调用实际的 greatfunction,并处理 great_function 的返回值,最终返回给 Python 环境。
导出表 GreateModuleMethods。它负责告诉 Python 这个模块里有哪些函数可以被 Python 调用。导出表的名字可以随便起,每一项有 4 个参数:第一个参数是提供给 Python 环境的函数名称,第二个参数是 greatfunction,即包裹函数。第三个参数的含义是参数变长,第四个参数是一个说明性的字符串。导出表总是以 {NULL, NULL, 0, NULL} 结束。
导出函数 initgreat_module。这个的名字不是任取的,是你的 module 名称添加前缀 init。导出函数中将模块名称与导出表进行连接。
在 Windows 下面,在 Visual Studio 命令提示符下编译这个文件的命令是 本部分参考资料
《Python 源码剖析 - 深度探索动态语言核心技术》是系统介绍 CPython 实现以及运行原理的优秀教程。
Python 官方文档的这一章详细介绍了 C/C++ 与 Python 的双向互动 Extending and Embedding the Python Interpreter _ _
关于编译环境,本文所述方法仅为出示原理所用。规范的方式如下:3. Building C and C++ Extensions with distutils _ _
作为字典使用的官方参考文档 Python/C API Reference Manual _ _
3、C/C++ 调用 Python(使用 Cython) 这其中有非 Python 关键字 cdef 和 public。这些关键字属于 Cython。由于我们需要在 C 语言中使用 "编译好的 Python 代码",所以得让 great_function 从外面变得可见,方法就以 "public" 修饰。而 cdef 类似于 Python 的 def,只有使用 cdef 才可以使用 Cython 的关键字 public。
这个函数中其他的部分与正常的 Python 代码是一样的。
接下来编译 great_module.pyx
在 Windows 下编译命令为
cl/LD dllmain.cgreat_module.c-IC:Python27includeC:Python27libspython27.lib
会得到一个 dllmain.dll。我们在 Excel 里面使用它,没错,传说中的 Excel 与 Python 混合编程: 参考资料:Cython 的官方文档,质量非常高:
4、Python 调用 C/C++(使用 SWIG)
swig-python mymodule.i
得到一个 mymodule_wrap.c 和一个 mymodule.py。把它编译为 Python 扩展:
Windows:
cl/LD mymodule_wrap.c/o_mymodule.pyd-IC:Python27includeC:Python27libspython27.lib
Linux:
gcc-fPIC-shared mymodule_wrap.c-o_mymodule.so-I/usr/include/python2.7/-lpython2.7
注意输出文件名前面要加一个下划线。
现在可以立即在 Python 下使用这个 module 了: 换句话说,SWIG 自动完成了诸如 Python 类型转换、module 初始化、导出代码表生成的诸多工作。
对于 C++,SWIG 也可以应对。例如以下代码有 C++ 类的定义:
由于 CPython 自身的结构设计合理,使得 Python 的 C/C++ 扩展非常容易。如果打算快速完成任务,Cython(C/C++ 调用 Python) 和 SWIG(Python 调用 C/C++) 是很不错的选择。但是,一旦涉及到比较复杂的转换任务,无论是继续使用 Cython 还是 SWIG,仍然需要学习 Python 源代码。
来源: http://www.raincent.com/content-85-10414-1.html