Python中如何用ctypes定义包含多种数据类型的结构体实例?
解决方案
步骤1:定义与C结构完全匹配的ctypes结构体
通过继承ctypes.Structure声明结构体,按C定义的顺序逐个指定字段名和对应数据类型:
import ctypes class ODBM(ctypes.Structure): _fields_ = [ ("datano", ctypes.c_short), # 对应C的short datano ("dummy", ctypes.c_short), # 对应C的short dummy ("mcr_val", ctypes.c_long), # 对应C的long mcr_val ("dec_val", ctypes.c_short), # 对应C的short dec_val ]
步骤2:规范DLL函数的参数类型(可选但强烈建议)
提前给DLL导出函数指定参数类型和返回值类型,避免ctypes默认类型转换带来的隐藏bug:
# 加载DLL fs = ctypes.cdll.LoadLibrary(r"你的DLL文件路径") # 指定cnc_rdmacro的参数类型:依次是unsigned short, short, short, ODBM指针 fs.cnc_rdmacro.argtypes = [ ctypes.c_ushort, ctypes.c_short, ctypes.c_short, ctypes.POINTER(ODBM) ] # 指定返回值类型为short fs.cnc_rdmacro.restype = ctypes.c_short
步骤3:调用函数并读取结构体字段
实例化结构体后通过ctypes.byref传入函数,调用完成后直接访问结构体实例的属性即可读取对应字段值:
# 实例化ODBM结构体 macro = ODBM() # 调用DLL函数,libh、macro_no替换为你实际的参数 ret = fs.cnc_rdmacro(libh, macro_no, 10, ctypes.byref(macro)) # 读取各字段值 print(f"变量编号: {macro.datano}") print(f"变量值: {macro.mcr_val}") print(f"小数位数: {macro.dec_val}")
说明
你之前用4个c_short数组可以正常运行属于巧合,本质是C结构体内存对齐规则下,刚好没有触发明显的内存越界错误,但long类型长度远大于short,在不同位数的运行环境下随时可能出现取值错误、程序崩溃等问题,用Structure定义才是符合规范的实现方案。
内容的提问来源于stack exchange,提问作者Srivatsan M
相关产品推荐
相关产品推荐

