一,python与C类型对应关系
最左边一列的ctypes type,以替代C库中的各种类型。
二,不带参数的调用
1,target.c
#include <stdio.h>void hello_world(){printf("hello downey!!\r\n");
}
2,执行命令编译动态连接库文件
gcc -shared -o libtarget.dll target.c
linux:
gcc --shared -fPIC -o target.c libtarget.so
windows:
gcc -shared -o libtarget.dll target.c
3,test.py
import ctypesif __name__ == '__main__':test = ctypes.windll.LoadLibrary("./libtarget.dll")test.hello_world()
4,输出
hello downey!!
三,带参数的调用
1,target.c
#include <stdio.h>char add(int a, int b){return a + b;
}char mul(int a, int b){return a * b;
}
2,执行编译命令
gcc -shared -o libtarget.dll target.c
3,test.py
from ctypes import *if __name__ == '__main__':# windll.LoadLibrary("./libtarget.dll") # woinows应该用windll ,但用cdll在windows下测测试也没问题。test = cdll.LoadLibrary("./libtarget.dll") # linux 用cdlltest.add.restype = c_inttest.mul.restype = c_intc = test.add(48,22)print(type(c))print(c)d = test.mul(48, 22)print(d)
4,输出
<class 'int'>
70
1056
四,结构体数据格式
1,target.c
#include <stdio.h>
#include <string.h>typedef struct{char *ptr;float f;char array[10];
}target_struct;target_struct* hello_world(target_struct* target){static char temp = 0x30;target->ptr = &temp;target->f = 3.1;memset(target->array,1,sizeof(target->array));return target;
}
2,执行编译命令
gcc -shared -o libtarget.dll target.c
3,test.py
from ctypes import *# 声明一个和结构体数据对应的数据结构类
# _fields_是字典类型,key要与C库中结构体相对应,value则是指定相应类型
class test_struct(Structure):_fields_ = [('ptr', c_char_p),('c', c_float),('array', c_char * 10)]if __name__ == '__main__':test = windll.LoadLibrary("./libtarget.dll")# 构造一个对应C中结构体的类,可以传入对应参数进行构造。struct = test_struct(c=0.5)#指定返回值类型为test_struct指针类型,这里的类型由POINTER()修饰,表示是指针类型test.hello_world.restype = POINTER(test_struct)# 调用hello_world()函数,传入struct类,pointer(struct)就是将struct转为指针类型实例。因为在C中的接口就是传入target_struct类型,返回target_struct类型,所以ret_struct也是target_struct*类型ret_struct = test.hello_world(pointer(struct))# 打印函数返回值,查看执行结果。对于一个指针类型的变量,如果我们要获取它的值,可以使用.contents方法print(ret_struct.contents.ptr)print(ret_struct.contents.c)
4,输出
b'0'
3.0999999046325684
五,参数传入函数引用,c调用python函数
1,target.c
#include <stdio.h>
#include <string.h>typedef void (*callback)(int);void func(callback c1,callback c2,int p1,int p2){c1(p1);c2(p2);
}
2,执行编译命令
gcc -shared -o libtarget.dll target.c
3,test.py
from ctypes import *def test_callback1(val):print("I'm callback1")print(val)def test_callback2(val):print("I'm callback2")print(val)if __name__ == '__main__':test = windll.LoadLibrary("./libtarget.dll")CMPFUNC = CFUNCTYPE(None, c_int)cbk1 = CMPFUNC(test_callback1)cbk2 = CMPFUNC(test_callback2)test.func(cbk1, cbk2, 1, 2)
4,输出
I'm callback1
1
I'm callback2
2
windos 安装gcc:
Mingw快捷安装教程 并完美解决出现的下载错误:The file has been downloaded incorrectly_mingw the file has been downloaded incorrectly-CSDN博客
参考:
python代码用c语言封装_python调用C语言接口-CSDN博客