int32_t 的复杂结构和 python ctypes 中的 char 数组
Complex structure of int32_t and char array in python ctypes
我正在尝试创建一个结构以在提供的 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 函数并检查它 return 如下:
dlllib = CDLL("some.dll")
somefunction = dlllib.some_function
somefunction.argtypes = [POINTER(INSTRUCT)]
INSTRUCT().size
INSTRUCT().num
print(np.ctypeslib.as_array(INSTRUCT().buf1))
但是,我只能 return 是 0
并且未被函数修改——等于在 C 函数调用之前定义的那个。
我不确定问题发生在哪个阶段,但是没有错误,代码执行正常。
不幸的是,我没有可用的 C 代码,只有函数的输入参数。
此致
数组定义错误。在 ctypes
中,需要反转数组索引以按照 C 的方式对数组进行索引。例如,Python 和 ctypes
中的 char buf[x][y]
等价于 buf = (c_char * y * x)()
。请注意,边界是相反的。否则,您的定义是正确的。
请注意,使用 c_char
将为数组值提供 return 个文本字符。如果您想要整数,请使用 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.
我正在尝试创建一个结构以在提供的 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 函数并检查它 return 如下:
dlllib = CDLL("some.dll")
somefunction = dlllib.some_function
somefunction.argtypes = [POINTER(INSTRUCT)]
INSTRUCT().size
INSTRUCT().num
print(np.ctypeslib.as_array(INSTRUCT().buf1))
但是,我只能 return 是 0
并且未被函数修改——等于在 C 函数调用之前定义的那个。
我不确定问题发生在哪个阶段,但是没有错误,代码执行正常。 不幸的是,我没有可用的 C 代码,只有函数的输入参数。
此致
数组定义错误。在 ctypes
中,需要反转数组索引以按照 C 的方式对数组进行索引。例如,Python 和 ctypes
中的 char buf[x][y]
等价于 buf = (c_char * y * x)()
。请注意,边界是相反的。否则,您的定义是正确的。
请注意,使用 c_char
将为数组值提供 return 个文本字符。如果您想要整数,请使用 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.