通过ctypes传递可变数量的自定义类型的参数

时间:2018-08-16 16:00:40

标签: python python-3.x ctypes

我有一个dll函数,可以接受可变数目的ICString类型的参数

class ICString(ctypes.Structure):
    _fields_ = [('len', c_long),
                ('text', c_char_p)]

这是我设置argtypes和函数参数的方式

num_params = len(argumentos)
self.__U2_C_INTERFACE.ic_malloc.argtypes = [POINTER(c_long)]
self.__U2_C_INTERFACE.ic_free.argtypes = [ctypes.c_voidp]
sub_name_in = c_char_p(bytes(subrutina,
                             self.__sistema_codificacion))
sub_name_len_in = c_long(len(subrutina))
num_params_len_in = c_long(num_params)
code = c_long(0)
p_in = [None]*num_params
argumentos_tipo = [c_char_p, POINTER(c_long), POINTER(c_long), POINTER(c_long)]
for idx, parametro in enumerate(argumentos):
    argumentos_tipo += [POINTER(ICString)]
    param_len = len(parametro)
    p_in[idx] = ICString(c_long(0))
    if param_len > 0:
        temp = self.__U2_C_INTERFACE.ic_malloc(byref(c_long(param_len)))
        memcpy_dest = ctypes.cast(temp, ctypes.c_char_p)
        ctypes.memmove(memcpy_dest, bytes(parametro, self.__sistema_codificacion),
                       param_len*sizeof(ctypes.c_char))
        p_in[idx].len = c_long(param_len)
        p_in[idx].text = memcpy_dest
self.__U2_C_INTERFACE.ic_subcall.argtypes = argumentos_tipo

但是我不知道如何将参数列表传递给函数,并且不做类似的事情

if num_params== 1
    self.__U2_C_INTERFACE.ic_subcall(sub_name_in, byref(sub_name_len_in), byref(code), 
            byref(num_params_len_in), byref(p_in[0]))
if num_params== 2
    self.__U2_C_INTERFACE.ic_subcall(sub_name_in, byref(sub_name_len_in), byref(code), 
            byref(num_params_len_in), byref(p_in[0]), byref(p_in[1]))
if num_params== 3
    self.__U2_C_INTERFACE.ic_subcall(sub_name_in, byref(sub_name_len_in), byref(code), 
            byref(num_params_len_in), byref(p_in[0]), byref(p_in[1]), byref(p_in[2]))

1 个答案:

答案 0 :(得分:2)

您可以使用参数解压缩(未使用,因为您的示例不是一段有效的代码):

self.__U2_C_INTERFACE.ic_subcall(sub_name_in, byref(sub_name_len_in), byref(code),
    byref(num_params_len_in), *[byref(n) for n in p_in])

请参阅: