You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 15:09:02