Reputation: 1782
I'm writing a ctypes interface to a 3rd party DLL (I have no control over the DLL).
My code seems to work, but I fear I'm setting up .argtypes
wrong.
The signature of the C function I'm trying to call is:
int GetData(unsigned short option, unsigned char* buffer, int bufferLength, int &actualLength);
option
indicates the kind of data requested, buffer
points to a buffer I supply, bufferLength
is the length of the buffer in bytes.
The DLL function writes into the buffer, and puts the number of bytes it actually wrote into actualLength
.
My code:
import ctypes
dll = ctypes.CDLL("dll_name.dll")
def GetData(option):
BUFSIZE = 6
buf = bytearray(BUFSIZE)
ptr_to_buf = (ctypes.c_char*len(buf)).from_buffer(buf)
actualLength = ctypes.c_int()
dll.GetData.argtypes = (ctypes.c_ushort,
ctypes.c_char_p,
ctypes.c_int,
ctypes.POINTER(ctypes.c_int))
dll.GetData.restype = int
dll.GetData(option,
ptr_to_buf,
BUFSIZE,
ctypes.byref(actualLength))
return (buf, actualLength.value)
Does the call to GetData()
accurately reflect the .argtypes?
ptr_to_buf
as a ctypes.c_char_p
as I'm doing here?ctypes.byref
into a ctypes.POINTER
as I'm doing here?.pointer
instead of .byref?
I did read the ctype docs, I know they say .byref
is faster, but I'm not clear on when .pointer
is needed.Upvotes: 0
Views: 557
Reputation: 177610
.argtypes
is fine. You may want POINTER(c_ubyte)
to completely agree with the prototype, but often c_char_p
is easier to work with.
- Is it OK to pass ptr_to_buf as a ctypes.c_char_p as I'm doing here?
Yes. An array is passed as a pointer of the same element type.
- Is it OK to pass a ctypes.byref into a ctypes.POINTER as I'm doing here?
Yes.
- When would be it be necessary to use .pointer instead of .byref? I did read the ctype docs, I know they say .byref is faster, but I'm not clear on when .pointer is needed.
Create a pointer
when you need a concrete pointer. I've rarely used pointer
. Say you had this code in C and had some reason to mimic it:
int x = 5;
int* y = &x;
The Python equivalent would be:
x = c_int(5)
y = pointer(x)
- Is there anything else I'm doing wrong here?
.restype
should have a ctype
type. .restype = c_int
would be correct.
Upvotes: 1