Python ctypes无法在结构中传递内存数组 [英] Python ctypes Unable to pass memory array in a structure
问题描述
Python 2.7.8,Windows 7,Phyton USB程序员的DLL
Python 2.7.8, Windows 7, Phyton USB programmer's DLL
我被困在应该是大内存阵列的Data元素上,我尝试使用多个不同的定义,但我无法理解错误试图告诉我什么。我遇到的大多数错误都是类型错误,下面的代码是我最近的错误,似乎正在调用该函数,但是由于该错误而无法处理。
I am stuck with the Data element which should be a large memory array, I have tried using several different definitions, but I cannot understand what the errors are trying to tell me. Most of the errors I have encountered have been type errors, this code below is the closest I have been, it seems to be calling the function, but it does not process due to the error.
C API:
typedef struct tagACI_Memory_Params
{
UINT Size; // (in) Size of structure, in bytes
UINT BufferNumber; // (in) Number of buffer of interest, the first buffer number is 0
UINT LayerNumber; // (in) Number of layer of interest, the first layer number is 0
DWORD AddressLow; // (in) Low 32 bits of address, in layer units (natural to device address)
DWORD AddressHigh; // (in) High 32 bits of address, in layer units (natural to device address)
PVOID Data; // (in || out) Pointer to data to read to or write from
DWORD DataSize; // (in) Size of data to read or write, in layer units, max. 16 MB (0x1000000)
DWORD FillValue; // (in) Value to fill buffer with, used by ACI_FillLayer() only
} ACI_Memory_Params;
我的python代码:
My python code:
MaxMemorySize = 1024
MemoryBuffer = ctypes.c_ubyte * MaxMemorySize
class Memory_Params(ctypes.Structure):
_fields_ = [("Size", ctypes.wintypes.UINT),
("BufferNumber", ctypes.wintypes.UINT),
("LayerNumber", ctypes.wintypes.UINT),
("AddressLow", ctypes.wintypes.DWORD),
("AddressHigh", ctypes.wintypes.DWORD),
("Data", MemoryBuffer ),
("DataSize", ctypes.wintypes.DWORD),
("FillValue", ctypes.wintypes.DWORD)
]
WriteLayer = ctypes.windll.ACI.ACI_WriteLayer
WriteLayer.argtypes = [ctypes.POINTER(Memory_Params)]
WriteLayer.restype = ctypes.HRESULT
WData = Memory_Params(ctypes.sizeof(Memory_Params),0,0,0,0,ctypes.POINTER(MemoryBuffer),15,0)
for i in range(10):
WData.Data[i] = i
print 'write result', WriteLayer(ctypes.byref(WData))
API调用返回1,表示:define ACI_ERR_INVALID_PARAMS_SIZE 1 // ACI函数中的无效结构大小
The API call returns a 1 which means: define ACI_ERR_INVALID_PARAMS_SIZE 1 // Invalid structure size in ACI function
更新:
我错过的关键事项:定义对象后创建和使用MemoryBuffer对象,以及如何正确定义指针。
如果其他任何人也有类似情况,请使用以下代码:
Update: The critical things I missed: Creating and using the MemoryBuffer object after defining it, and how to correctly define the pointer. If anyone else has a similar situation, here is working code:
MaxMemorySize = 1024
MemoryBuffer = ctypes.c_ubyte * MaxMemorySize
class Memory_Params(ctypes.Structure):
_fields_ = [("Size", ctypes.wintypes.UINT),
("BufferNumber", ctypes.wintypes.UINT),
("LayerNumber", ctypes.wintypes.UINT),
("AddressLow", ctypes.wintypes.DWORD),
("AddressHigh", ctypes.wintypes.DWORD),
("Data", ctypes.POINTER(ctypes.c_ubyte) ),
("DataSize", ctypes.wintypes.DWORD),
("FillValue", ctypes.wintypes.DWORD)
]
WriteLayer = ctypes.windll.ACI.ACI_WriteLayer
WriteLayer.argtypes = [ctypes.POINTER(Memory_Params)]
WriteLayer.restype = ctypes.wintypes.UINT
PData = MemoryBuffer()
WData = Memory_Params(ctypes.sizeof(Memory_Params),0,0,0,0,PData,for i in range(10):
PData[i] = i
WriteLayer(ctypes.byref(WData))
推荐答案
- 初始化 WData 对象时,第6 th 参数为 ctypes.POINTER(MemoryBuffer)。这是(或在语法上应该是错误的): POINTER 返回指针 type ,而您需要一个 unsigned char 数组(这是一个 object 或类型的 instance )
- 您收到的大小错误是因为 Python 结构没有与 C 不匹配。 C 中的 Data 成员是一个 PVOID ,它是一个大小为8的指针(如果您具有 32bit,则为4 Python ),而在 Python 中,它具有 MemoryBuffer 类型,大小为1024
- When you initialize the WData object, the 6th argument is ctypes.POINTER(MemoryBuffer). This is (or should be syntactically) incorrect: POINTER returns a pointer type, while you need an unsigned char array (which is an object or an instance of a type)
- The size error that you get is because the Python structure doesn't match the C one. The Data member in C is a PVOID, which is a pointer with a size of 8 (or 4 if you have a 32bit Python), while in Python it has the MemoryBuffer type which has a size of 1024
要解决此问题,请使您的 Memory_Params.Data 成员类型为:
ctypes.POINTER(ctypes.c_ubyte)
To correct the problem, make your Memory_Params.Data member's type: ctypes.POINTER(ctypes.c_ubyte)
这篇关于Python ctypes无法在结构中传递内存数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!