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

使用ctypes动态设置CDLL中任意函数restype失败的解决方法咨询

使用ctypes动态设置CDLL中任意函数restype失败的解决方法咨询

你遇到的这个问题其实是ctypes的一个特性导致的:当你用mydll['函数名']这种索引方式访问DLL函数时,每次都会返回一个全新的函数对象。这意味着你前一次给它设置的restype会被直接丢弃,下一次通过索引调用时,拿到的又是默认返回ctypes.c_long的新对象,自然就取不到正确的字符串结果了。而用属性访问(mydll.函数名)的方式时,ctypes会缓存这个函数对象,所以你设置的restype能一直生效。

解决这个问题的核心思路是:先把函数对象存储到一个变量里,再对这个变量配置restype和argtypes,之后始终通过这个变量调用函数,避免每次都从DLL索引中获取新对象。

基础解决写法

直接修改你的代码,先把函数对象存下来:

import ctypes

mydll = ctypes.CDLL(libName)
# 先将函数对象赋值给变量
target_func = mydll['GET_LAST_MESSAGE']
# 对变量进行配置
target_func.argtypes = None
target_func.restype = ctypes.c_char_p
# 通过变量调用函数
message = target_func()

类封装的进阶方案

考虑到你需要封装一个类来处理任意函数的加载,我们可以加入缓存机制,把已经配置好的函数对象存起来,避免重复创建和配置:

import ctypes

class DLLHandler:
    def __init__(self, lib_name):
        self.dll = ctypes.CDLL(lib_name)
        # 用字典缓存已配置的函数对象
        self._cached_functions = {}
    
    def get_function(self, func_name, restype=None, argtypes=None):
        # 如果函数未缓存,就创建并配置
        if func_name not in self._cached_functions:
            func = self.dll[func_name]
            if argtypes is not None:
                func.argtypes = argtypes
            if restype is not None:
                func.restype = restype
            self._cached_functions[func_name] = func
        # 返回缓存的函数对象
        return self._cached_functions[func_name]

# 使用示例
handler = DLLHandler(libName)
# 获取并配置指定函数
get_last_msg = handler.get_function('GET_LAST_MESSAGE', restype=ctypes.c_char_p)
# 调用函数
message = get_last_msg()

这样无论你动态传入什么函数名,都能确保配置的restype和argtypes不会丢失,完美适配类封装的需求。

备注:内容来源于stack exchange,提问作者Victor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 10:43:01