Python用ctypes封装C DLL到类时触发缺少参数TypeError如何解决
错误原因
你定义的my_outer_class的构造方法__init__声明了两个必须传入的位置参数py_function_1和py_function_2,但你实例化类的时候myapi = my_outer_class()没有传任何参数,直接触发了参数缺失的报错。而且实际上你构造方法里根本没用到这两个传入的参数,都是直接从加载好的DLL对象test里取的函数,这两个参数属于多余定义。
解决方法
直接删掉__init__方法里多余的两个入参即可,同时还可以进一步优化封装逻辑,把DLL加载、结构体定义都收拢到类内部,避免全局变量污染,方便后续扩展其他DLL接口。
优化后的完整可运行代码
import ctypes # 把所有DLL对接逻辑收拢到同一个类中 class MyDllWrapper: # 类常量和结构体定义放在类内部,和DLL头文件定义对齐 MAX_LENGTH = 63 class Struct1(ctypes.Structure): _fields_ = [ ("param1", ctypes.c_ubyte), ("param2", ctypes.c_uint32), ("param3", ctypes.c_ubyte), ("param4", ctypes.c_char * MAX_LENGTH) ] def __init__(self, dll_path: str = "Project.dll"): # 构造方法里只需要传入DLL路径,自动完成加载和函数签名初始化 self._dll = ctypes.WinDLL(dll_path) # 初始化所有DLL函数的参数类型和返回值类型 self._init_function_signatures() def _init_function_signatures(self): # 封装function1 self.function_1 = self._dll.function_1 self.function_1.argtypes = (ctypes.c_uint8, ctypes.c_uint8) self.function_1.restype = ctypes.c_int # 封装function2 self.function_2 = self._dll.function_2 self.function_2.argtypes = (ctypes.c_uint8, ctypes.c_uint8) self.function_2.restype = ctypes.c_int # 后续扩展其他函数直接在这里加即可 # 比如sum、mul、message、message_2都可以在这里统一初始化签名 # 还可以进一步封装结构体创建、message_2调用等工具方法,简化上层调用 def create_struct1(self, param1: int, param2: int, param3: int, param4: str) -> Struct1: return self.Struct1( param1=param1, param2=param2, param3=param3, param4=param4.encode("utf-8") ) def call_message_2(self, struct_instance: Struct1): self._dll.message_2(ctypes.byref(struct_instance)) # 使用示例 if __name__ == "__main__": # 实例化类,不需要传多余参数 dll_api = MyDllWrapper() # 调用封装好的函数 res1 = dll_api.function_1(255, 255) print(res1) res2 = dll_api.function_2(255, 255) print(res2)
额外注意点
- 你原来的代码里写的是
argtype,正确的ctypes属性名是argtypes(复数),虽然部分场景下单数也能生效,但标准写法是复数,避免出现未知问题。 - 把DLL加载、结构体定义都收拢到类内部后,后续要修改DLL路径、新增接口都只需要改这个类即可,符合封装的设计目标。
内容的提问来源于stack exchange,提问作者pekoms
相关产品推荐
相关产品推荐

