Python 2.7.8, Windows 7, Phyton USB programmer's DLL
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;
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))
The API call returns a 1 which means: define ACI_ERR_INVALID_PARAMS_SIZE 1 // Invalid structure size in ACI function
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))
ctypes.POINTER(MemoryBuffer)
. This is (or should be syntactically) incorrect: POINTER returns a pointer type, while you need anunsigned char
array (which is an object or an instance of a type)To correct the problem, make your
Memory_Params.Data
member's type:ctypes.POINTER(ctypes.c_ubyte)