Python 在ctypes中部分定义结构定义
我不太熟悉Python-C接口,我使用的是C SDK 有一个结构称为Python 在ctypes中部分定义结构定义,python,ctypes,Python,Ctypes,我不太熟悉Python-C接口,我使用的是C SDK 有一个结构称为NET\u它的\u PLATE\u结果,我只需要从API回调函数中检索dwSize和byPicNo 在回调函数(Python)中,我将使用memmove函数复制结果内存块。只定义部分struct并且仍然能够得到我想要的实际结果,这是一种好的做法吗?就像我在下面定义的那样 class NET_ITS_PLATE_RESULT(ctypes.Structure): _fields_ = [ ("dwSize
NET\u它的\u PLATE\u结果
,我只需要从API回调函数中检索dwSize
和byPicNo
在回调函数(Python)中,我将使用memmove
函数复制结果内存块。只定义部分struct
并且仍然能够得到我想要的实际结果,这是一种好的做法吗?就像我在下面定义的那样
class NET_ITS_PLATE_RESULT(ctypes.Structure):
_fields_ = [
("dwSize", ctypes.c_uint),
("byPicNo", ctypes.c_byte)
]
从文档中:NET\u它的板\u结果(实际定义要长得多)
为了简单起见,在提到结构大小时,我将忽略(4字节默认)内存对齐,并将它们视为一个字节的对齐方式,以便结构的大小等于其成员大小之和 例如:
>>导入ctypes
>>>
>>>类Struct0(ctypes.Structure):#您的网络_其PLATE RESULT结构,名称较短
... _字段=[
…(“dwSize”,ctypes.c_uint),
…(“byPicNo”,ctypes.c_字节)
... ]
...
>>>
>>>
>>>类Struct0Pack001(ctypes.Structure):
... _包装=1
... _字段=[
…(“dwSize”,ctypes.c_uint),
…(“byPicNo”,ctypes.c_字节)
... ]
...
>>>
>>>打印(ctypes.sizeof(Struct0))
8.
>>>打印(ctypes.sizeof(Struct0Pack001))
5.
当回调函数的调用者调用它时,它将尝试填充其NET\u-its\u-PLATE\u结果参数(如果参数是指针(很可能是指针),则填充到参数所指向的内存,如果不是指针,则直接填充到堆栈上),从而写入sizeof(净其板结果)
(16)字节—正如它所期望的那样
但是您将只传递5字节,因此SDK将尝试在其“允许”内存区域之外写入,从而导致未定义的行为。您可能会遇到SEGFULTS(访问冲突)
另外,考虑到程序将通过上述阶段,因为您删除了一些字段(dwMatchNo、byGroupNum),所以您将无法在byPicNo中获得正确的数据,而是在dwMatchNo的第一个字节中获得正确的数据
所以,永远不要选择像这样的快捷方式,除非你真的知道自己在做什么,以及处理它们的代码在做什么——这里似乎不是这样
嗯,看看dwSize成员,我想到的是MS结构(例如),其第一个成员是它们的大小,在将结构(指针)传递给正在填充其(相关)的API之前,需要相应地设置它成员们。检查这个场景也很有意思。但无论如何,它都不可能与建议的网络板结果一起工作。为了简单起见,在提到结构大小时,我将忽略(4字节默认值)内存对齐,并像对齐一个字节一样,使结构的大小等于其成员大小之和 例如:
>>导入ctypes
>>>
>>>类Struct0(ctypes.Structure):#您的网络_其PLATE RESULT结构,名称较短
…\u字段=[
…(“dwSize”,ctypes.c_uint),
…(“byPicNo”,ctypes.c_字节)
... ]
...
>>>
>>>
>>>类Struct0Pack001(ctypes.Structure):
…\u块=1
…\u字段=[
…(“dwSize”,ctypes.c_uint),
…(“byPicNo”,ctypes.c_字节)
... ]
...
>>>
>>>打印(ctypes.sizeof(Struct0))
8.
>>>打印(ctypes.sizeof(Struct0Pack001))
5.
当回调函数的调用者调用它时,它将尝试填充其NET\u-its\u-PLATE\u结果参数(如果参数是指针(很可能是指针),则填充到参数所指向的内存,如果不是指针,则直接填充到堆栈上),从而写入sizeof(净其板结果)
(16)字节—正如它所期望的那样
但是您将只传递5字节,因此SDK将尝试在其“允许”内存区域之外写入,从而导致未定义的行为。您可能会遇到SEGFULTS(访问冲突)
另外,考虑到程序将通过上述阶段,因为您删除了一些字段(dwMatchNo、byGroupNum),所以您将无法在byPicNo中获得正确的数据,而是在dwMatchNo的第一个字节中获得正确的数据
所以,永远不要选择像这样的快捷方式,除非你真的知道自己在做什么,以及处理它们的代码在做什么——这里似乎不是这样
嗯,看看dwSize成员,我想到的是MS结构(例如),其第一个成员是它们的大小,在将结构(指针)传递给正在填充其(相关)的API之前,需要相应地设置它各位成员。检查此场景也很有意思。但无论如何,它都不可能与建议的网络板结果一起工作。感谢您的详细解释!感谢您的详细解释!
struct{
DWORD dwSize;
DWORD dwMatchNo;
BYTE byGroupNum;
BYTE byPicNo;
BYTE bySecondCam;
BYTE byFeaturePicNo;
BYTE byDriveChan;
BYTE byVehicleType;
BYTE byDetSceneID;
BYTE byVehicleAttribute;
}NET_ITS_PLATE_RESULT, *LPNET_ITS_PLATE_RESULT;