众所周知,Python的执行效率是无法同C比的。而且有些算法已经有开源的C库了,我们也没必要用Python重写一份。又或者我们自己使用C语言写的函数如何被python使用呢?一种方便的方法就是Python提供的ctypes库,它提供同C语言兼容的数据类型,可以很方便地调用C语言动态链接库中的函数。当然python还自带扩展功能,但是扩展功能需要修改C代码本身,这样就造成C语言写的程序不够纯粹,毕竟夹杂了很多适配python的东西。我们使用ctypes库来调用C的函数。
ctypes 的官方文档可以参考:https://docs.python.org/2/library/ctypes.html
一、首先准备C函数:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
struct segment{
int key;
}
struct content{
struct segment seg;
int value
}
struct content g_conent;
int set_kv(int key,int value);
struct content *get_content();
#include "ctest.h"
int set_kv(int key,int value)
{
g_content.seg.key=key;
g_content.value=value;
return 0;
}
struct content *get_content()
{
return &g_content;
}
二、编译成动态库so文件:gcc ctest.c -fPIC -shared -o ctest.so
前期准备工作完成。
三、编写python代码
from ctypes import *
libctest = cdll.LoadLibrary('ctest.so')
class segment_py(Structure):
_fields_=[("key",c_int)]
class content_py(Structure):
_fields_=[("seg",segment_py),
("value",c_int)]
libctest.get_content.restype=POINTER(content_py)
def test():
con=content_py()
libctest.set_kv(1,10)
con=libctest.get_content()
print "key:%s value:%s " % (con.seg.key,con.value)
if __name__ == '__main__'
test()
ctypes定义了一系列基本C数据类型:
ctypes类型 | C类型 | Python类型 |
c_char | char | 1个字符的字符串 |
c_wchar | wchar_t | 1个字符的unicode字符串 |
c_byte | char | int/long |
c_ubyte | unsigned char | int/long |
c_short | short | int/long |
c_ushort | unsigned short | int/long |
c_int | int | int/long |
c_uint | unsigned int | int/long |
c_long | long | int/long |
c_ulong | unsigned long | int/long |
c_longlong | __int64 或 long long | int/long |
c_ulonglong | unsigned __int64 或 unsigned long long | int/long |
c_float | float | float |
c_double | double | float |
c_char_p | char * (NUL结尾字符串) | string或None |
c_wchar_p | wchar_t * (NUL结尾字符串) | unicode或None |
c_void_p | void * | int/long或None |