python ctypes中int32_t和char数组的复杂结构

2024-06-28 19:30:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个结构,以便在提供的C库(DLL)中使用, 如何定义以下结构(在文档中给出)

#define A 10
#define B 20
typedef struct
{
int32_t size;
int32_t num;
char buf1[A][B];
char buf2[A][B];
char buf3[A][B];
} INSTRUCT;

我尝试使用ctypes在python中定义它如下:

from ctypes import*

char_buff1 = ((c_char * 10) * 20)
char_buff2 = ((c_char * 10) * 20)
char_buff3 = ((c_char * 10) * 20)


class INSTRUCT(Structure):
    _fields_=[("size",c_int32),("num",c_int32),("buf1",char_buff1),("buf2",char_buff2),("buf3",char_buff3)]

ctypes中的int32_t可以替换为c_int_32吗? 这是定义结构的正确方法吗

然后,我尝试将结构指针馈送到DLL函数,并检查它返回的内容,如下所示:

dlllib = CDLL("some.dll")
somefunction = dlllib.some_function
somefunction.argtypes = [POINTER(INSTRUCT)]

INSTRUCT().size
INSTRUCT().num
print(np.ctypeslib.as_array(INSTRUCT().buf1))

但是,我只能确定返回值是0且未被函数修改——等于C函数调用之前定义的返回值

我不确定问题发生在哪个阶段,但是,没有错误,代码正常执行。 不幸的是,我没有可用的C代码,只有函数的输入参数

致意


Tags: 函数size定义ctypes结构numdllinstruct
1条回答
网友
1楼 · 发布于 2024-06-28 19:30:58

数组定义错误。在ctypes中,数组索引需要反转,以便像C那样索引数组。例如,Python中char buf[x][y]ctypes的等价物是buf = (c_char * y * x)()。请注意,边界是反向的。否则,您的定义是正确的

请注意,使用c_char将返回数组值的文本字符。如果需要整数,请使用c_int8。我将在下面使用后者

例如:

from ctypes import *
import numpy as np

A,B = 10,20
ARRAY = c_int8 * B * A   # build as B,A

class INSTRUCT(Structure):
    _fields_=[("size",c_int32),
              ("num",c_int32),
              ("buf1",ARRAY),
              ("buf2",ARRAY),
              ("buf3",ARRAY)]

i = INSTRUCT()
i.buf1[9][19] = 1  # access indices as A,B
print(np.ctypeslib.as_array(i.buf1))
[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]]  # 1 in correct location

您的访问示例使用了INSTRUCT(),它每次都会创建一个新的归零对象。创建单个实例并将其传递给如下函数:

dlllib = CDLL("some.dll")
somefunction = dlllib.some_function
somefunction.argtypes = [POINTER(INSTRUCT)]

i = INSTRUCT()          # make an instance
somefunction(byref(i))  # byref() passes address of a ctypes object.

相关问题 更多 >