我对Python-C接口不熟悉,并且正在使用C SDK。
有一个名为NET_ITS_PLATE_RESULT
的结构,我只需要从API回调函数中检索dwSize
和byPicNo
。
在回调函数(Python)中,我将使用memmove
函数复制结果存储块。仅定义部分struct
并且仍然能够获得所需的实际结果是一种好习惯吗?就像我在下面定义的那样
class NET_ITS_PLATE_RESULT(ctypes.Structure):
_fields_ = [
("dwSize", ctypes.c_uint),
("byPicNo", ctypes.c_byte)
]
摘自文档: NET_ITS_PLATE_RESULT (实际定义要长得多)
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;
答案 0 :(得分:0)
为简单起见,在提到结构大小时,我将忽略(默认为4字节)内存对齐,并像将它们一个字节对齐一样,以便结构的大小等于其成员大小的总和。
示例:
>>> import ctypes >>> >>> class Struct0(ctypes.Structure): # Your NET_ITS_PLATE_RESULT structure, with a shorter name ... _fields_ = [ ... ("dwSize", ctypes.c_uint), ... ("byPicNo", ctypes.c_byte) ... ] ... >>> >>> >>> class Struct0Pack001(ctypes.Structure): ... _pack_ = 1 ... _fields_ = [ ... ("dwSize", ctypes.c_uint), ... ("byPicNo", ctypes.c_byte) ... ] ... >>> >>> print(ctypes.sizeof(Struct0)) 8 >>> print(ctypes.sizeof(Struct0Pack001)) 5
当回调函数的调用者(来自其他问题的 SDK )将调用它时,它将尝试填充其 NET_ITS_PLATE_RESULT 自变量(如果自变量是指针(最有可能)则指向自变量所指向的内存,或者如果不是,则直接指向堆栈),因此要写sizeof(NET_ITS_PLATE_RESULT)
( 16 < / em> )字节-希望使用这种结构。
但是您只会传递 5 个字节,因此, SDK 将尝试在其“允许的”存储区域之外进行写入导致 未定义的行为 。您可能会得到 segfault s(访问冲突 s)。
此外,考虑到该程序将通过上述阶段,因为您消除了某些字段( dwMatchNo , byGroupNum ),所以您将无法在其中获得正确的数据您的 byPicNo ,但 dwMatchNo 的1个 st 字节。
因此,永远不要追求像这样的快捷方式,除了您真正知道自己在做什么以及处理这些代码的代码是什么外,这似乎并非如此。
嗯,看着 dwSize 成员,我想到的是1 st 成员的 MS 结构(例如[MS.Docs]: OSVERSIONINFOEXW structure)是它们的大小,需要在将结构(指针)传递到填充其(相关)成员的 API 之前进行相应的设置。同样,检查这种情况也会很有趣。但无论如何,它不可能与建议的 NET_ITS_PLATE_RESULT 一起使用。