【Python】C++ & Python 混合编程(5)-- Python 调用 C++(ctypes)

  • ctypes 是 python 内建的模块,可以实现 python 直接调用动态链接库
  • 提供了一套数据类型,实现 C 类型到 python的映射
  • 对C++支持较差,特别是复杂类型
  • 当手头只有第三方动态链接库时,ctypes 比较方便(否则建议用SWIG包装)

使用方法

1)加载DLL

from ctypes import *

# 针对 WinDLL 类的对象
objdll = windll.LoadLibrary(dllpath)
objdll = WinDLL(dllpath)

# 针对 CDLL 类的对象
objdll = cdll.LoadLibrary(dllpath)
objdll = CDLL(dllpath)

2)声明函数的输入和输出类型

# argtypes 声明输入类型
objdll.my_func.argtypes = [c_char_p, c_int, c_double]

# restype 声明输出类型
# 默认返回 c_int 类型
objdll.my_func.restype = c_char_p

3)函数调用

res = objdll.my_func(...)

语法细节

1)基本 C 类型的映射
完整表格见官方文档

C typePython typectypes type
Boolboolc_bool
charstringc_char
wchar_tunicode stringc_wchar
intint/longc_int
floatfloatc_float
doublefloatc_double
char*string/Nonec_char_p
void*int/long/Nonec_void_p

2)数组

# 整形数组
type_int_array_10 = c_int * 10
my_array = type_int_array_10()
my_array[2] = c_int(5)

3)类型指针和引用

# 使用 POINTER
type_p_int = POINTER(c_int)
v_int = c_int(4)
p_int = type_p_int(v_int)

# 或者使用 pointer (相当于 & )
p_int = pointer(v_int)

# 使用 contents 获取指针指向的对象(相当于 * )
p_int.contents
p_int[0]

# 使用 byref 传递引用参数
f_value = c_float(2)
objdll.func(byref(f_value))

4)函数指针

# 函数原型
int compar(const int*, const int*)

# 使用 CFUNCTYPE 创建 ctypes 的函数指针类型
CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))

# 定义一个 python 下的函数
def py_cmp_func(a, b):
    return a[0]-b[0]

# 获得对应 C 函数的函数指针
p_c_cmp_func = CMPFUNC(py_cmp_func)

5)结构体、联合体类型
ctypes 里定义了 Structure 和 Union 基础类,必须对其做继承,并用 fields 定义属性

from ctypes import *  

class Test1(Structure):  
    _fields_ = [('x', c_int),  
                ('y', c_char)] 

test1 = Test1(1,2)

# 包含指向结构体指针的情况
class Test2(Structure):  
    pass  
Test2._fields_ = [('x', c_int),  
                ('y', c_char),  
                ('next', POINTER(Test2))]  

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值