跨文件导入返回指针的DLL函数时,返回数值而非指针对象问题
解决ctypes调用DLL返回指针在导入后变为内存地址的问题
核心原因
ctypes默认将DLL函数的返回值视为c_int类型,直接运行runner.py时可能因模块内预先设置的类型上下文自动处理为指针对象,但跨模块导入时,类型配置未正确继承,导致返回的指针被转换为单纯的内存地址数值。
解决方案
1. 显式指定DLL函数的返回类型
在runner.py中必须明确设置GetPosition的返回类型为对应数据结构的指针,不能依赖默认行为。
首先定义与DLL返回结构匹配的ctypes结构体(需根据90+N+T+K字节的实际结构调整字段):
from ctypes import * class PositionStruct(Structure): _fields_ = [ # 示例字段,请替换为DLL文档定义的实际结构 ("account_id", c_long), ("position_detail", c_char * 80), # 补充其他字段以匹配总字节数要求 ]
然后在模块级别加载DLL并设置函数返回类型:
# 全局加载DLL,确保导入时完成初始化 profit_dll = windll.LoadLibrary("ProfitDLL64.dll") # 显式指定返回类型为自定义结构体的指针 profit_dll.GetPosition.restype = POINTER(PositionStruct)
2. 规范printPosition函数实现
确保函数返回的是ctypes指针对象,而非内存地址数值:
def printPosition(): ptr = profit_dll.GetPosition() if ptr: # 解析结构体内容 position_data = ptr.contents # 示例:打印数据 print(f"账户ID: {position_data.account_id}") # 返回ctypes指针对象,禁止转换为int类型返回 return ptr
3. 正确跨模块导入调用
在其他文件中直接导入并使用,此时返回的将是可正常解析的指针对象:
from runner import printPosition position_ptr = printPosition() if position_ptr: # 正常解析结构体内容 data = position_ptr.contents # 后续数据处理逻辑
关键注意点
- 不要在函数内部重复加载DLL,应在模块级别全局加载,避免类型设置失效
- 绝对不要将指针对象转换为整数返回,否则无法通过
cast恢复为指针类型 - 结构体的字段定义必须严格匹配DLL返回的数据结构,字节数要完全对应
90+N+T+K的要求
内容的提问来源于stack exchange,提问作者Nilton Schumacher F
相关产品推荐
相关产品推荐

