简体   繁体   English

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

[英]Complex structure of int32_t and char array in python ctypes

I am trying to create a structure to use in a C library provided (DLL), How the following structure (given in the documentation) can be defined?我正在尝试创建一个结构以在提供的 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;

My attempt to define it in python using ctypes was like so:我尝试使用 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)]

Can int32_t be replaced with c_int_32 in ctypes? ctypes中的int32_t可以替换成c_int_32吗? Is it correct way to define the structure?定义结构的方法是否正确?

Then I tried to feed the pointer of the structure to the DLL function and check what it returns as follows:然后我尝试将结构的指针提供给 DLL function 并检查它返回的内容如下:

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

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

However, I can only the return is 0 and unmodified by the function -- equal to the one defined before the C function call.但是,我只能返回0并且未经 function 修改——等于在 C function 调用之前定义的那个。

I am not sure at which stage the problem occurs, however, there are no errors, the code executes normally.我不确定问题发生在哪个阶段,但是,没有错误,代码正常执行。 Unfortunately, I don't have the C code available, only the input parameters for the function.不幸的是,我没有可用的 C 代码,只有 function 的输入参数。

Best regards此致

The array definition is wrong.数组定义错误。 In ctypes , the array indices need to be reversed to index the array the way C does.ctypes中,需要反转数组索引以按照 C 的方式索引数组。 For example, the equivalent of char buf[x][y] in Python with ctypes is buf = (c_char * y * x)() .例如,与ctypes的 Python 中的char buf[x][y]的等价物是buf = (c_char * y * x)() Note that the bounds are reversed.请注意,边界是相反的。 Otherwise, your definition was correct.否则,您的定义是正确的。

Note that using c_char will return text characters for array values.请注意,使用c_char将返回数组值的文本字符。 If you want integers, use c_int8 .如果您想要整数,请使用c_int8 I'll use the latter below.我将在下面使用后者。

Example:例子:

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

Your example of accessing used INSTRUCT() which creates a new, zeroed object each time.您访问使用的INSTRUCT()的示例每次都会创建一个新的、归零的 object。 Create a single instance and pass it to a function like so:创建一个实例并将其传递给 function,如下所示:

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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM