I have a DLL containing a C function with a prototype like this:
int c_read_block(uint32 addr, uint32 *buf, uint32 num);
I want to call it from Python using ctypes. The function expects a pointer to a chunk of memory, into which it will write the results. I don't know how to construct and pass such a chunk of memory. The ctypes documentation isn't much help.
Constructing an array and passing it "byref", like this:
cresult = (c_ulong * num)() err = self.c_read_block(addr, byref(cresult), num)
Gives this error message:
ArgumentError: argument 3: <type 'exceptions.TypeError'>: expected LP_c_ulong instance instead of pointer to c_ulong_Array_2
I guess that is because the Python ulong array is nothing like a c uint32 array. Should I use create_char_string
. If so, how do I persuade Python to "cast" that buffer to an LP_c_ulong?
ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python.
Creating Pointers with ctypesPOINTER() takes as parameter the type of pointer you wish to create, an integer pointer for example. ctypes. pointer() takes as parameter an object, which it then returns a pointer to. The pointer() however, only accepts datatypes from the ctypes module.
The built-in ctypes module is a powerful feature in Python, allowing you to use existing libraries in other languages by writting simple wrappers in Python itself. Unfortunately it can be a bit tricky to use. In this article we'll explore some of the basics of ctypes .
You can cast with the cast
function :)
>>> import ctypes >>> x = (ctypes.c_ulong*5)() >>> x <__main__.c_ulong_Array_5 object at 0x00C2DB20> >>> ctypes.cast(x, ctypes.POINTER(ctypes.c_ulong)) <__main__.LP_c_ulong object at 0x0119FD00> >>>
You can cast the result, but ctypes
allows you to use an array in place of a pointer, directly. The issue is the byref
in your code (which would be the equivalent of a pointer to a pointer):
So instead of:
cresult = (c_ulong * num)() err = self.c_read_block(addr, byref(cresult), num)
try:
cresult = (c_ulong * num)() err = self.c_read_block(addr, cresult, num)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With