如何再Python中调用C代码函数方法详解

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

 

你可能感兴趣的:(python)