kikaylee 2017-04-30
Python作为一门脚本语言有着非常好的易用性,但是很多人会病垢或纠结它的性能,不过Python与C/C++有着很好的沟通,很多对性能要求高的算法都可以用C/C++实现后供Python调用。
Python通过C/C++进行扩展有很多方法:
直接调用动态库.so
CPython使用C语言API编写模块include
使用boost_python封装C++类
使用SWIG扩展Python
以Python使用科大讯飞语言识别的Linux接口来介绍Python如何调用动态库.so文件。
1. Linux下生成动态库.so文件
以下是c实现的一个简单函数(mylib.c):
<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> {<br><span class="hljs-keyword">int</span> sum(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b) {<br><span class="hljs-keyword">return</span> a+b;<br> }<br>}
在shell中执行如下命令就会得到mylib.so动态库:
g++ <span class="hljs-operator">-f</span>PIC -shared -o libmylib.so mylib.c
2. 使用Python调用动态库
<span class="hljs-comment">#! /usr/bin/env python</span><br><br><span class="hljs-keyword">import</span> ctypes<br><span class="hljs-keyword">import</span> os<br><br>mylib = ctypes.CDLL(os.getcwd() + <span class="hljs-string">'/libmylib.so'</span>)<br><span class="hljs-keyword">print</span> mylib.sum(<span class="hljs-number">2</span>,<span class="hljs-number">6</span>)
3. Python调用科大讯飞语音识别API
加载动态库:
xflib = ctypes.cdll.LoadLibrary(<span class="hljs-string">'msc/libmsc.so'</span>)
在Python里面调用C函数时主要是注意参数的类型。语音识别的接口如下:
接口函数:
<span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span>* MSPAPI QISRSessionBegin( <span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span>* grammarList, <span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span>*<br>params, <span class="hljs-keyword">int</span>* errorCode )
返回的是一个char指针作为sessionID以供后续接口使用,在Python里面要用ctypes.c_voidp类型:
ret = ctypes.c_int()<br>sessionId = ctypes.c_voidp()<br>sessionId = xflib.QISRSessionBegin(<span class="hljs-keyword">None</span>, param1, ret)
调用其它接口函数时,还可能用到如下ctypes的类型和接口:
ctypes.create_string_buffer()
ctypes.addressof()
ctypes.byref()
ctypes.string_at()
ctypes.c_char_p()
ctypes.c_uint()
关于ctypes的更详细说明可以参考官方文档