I'm writing a ctypes interface to a 3rd party DLL (I have no control over the DLL).
I've gotten to the point where I can get the DLL function's data (written into a buffer I supply) into a Python bytearray.
How do I convert the bytes in the bytearray into Python integers, strings, etc? I know how to brute-force it - for example (array[0] * 256 + array[1]) but that's dependent on machine endianness and crude.
What's the right way to do this?
The signature of the C function I'm trying to call is:
int GetData(int handle, unsigned short id, unsigned char* data, int dataLength, int &actualLength)
data
points to a buffer I supply, dataLength
is the length of the buffer in bytes.
The DLL function GetData()
writes into the buffer, and puts the number of bytes it actually wrote into actualLength
.
It returns an error code as an int (0 means OK).
Here's my code so far - it seems to work as far as it goes:
import ctypes
dll = ctypes.CDLL("dll_name.dll")
def GetData(handle, option_id):
BUFSIZE = 6
buffer = bytearray(BUFSIZE)
argument = (ctypes.c_char*len(buffer)).from_buffer(buffer)
actualLength = ctypes.c_int()
dll.GetData.argtypes = (ctypes.c_int, ctypes.c_ushort,
ctypes.c_char_p, ctypes.c_int, ctypes.POINTER(ctypes.c_int))
dll.GetData.restype = int
r = dll.GetData(hCam, option_id, argument, BUFSIZE, ctypes.byref(actualLength))
if r:
raise MyError(ERROR_CODES[r])
return (buffer, actualLength)
That returns a buffer that looks like (for example):
bytearray(b'\x01\x01\x00\x12\x00\x00')
I'm aware that the first two bytes represent a uint16 with the value 257. But how to read that out of the bytesarray in a Pythonic way?
Also, I'm not sure if I'm setting up .argtypes correctly - when should I be using c_char_p, c_void_p, .pointer, and .byref? (Altho, this does seem to work.) I did read the ctype docs, I know they say .byref is faster, but I'm not clear on when .pointer is preferred.