众所周知,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
#include
#include
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 |