Pointers and arrays in Python ctypes
Solution 1
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>
>>>
Solution 2
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)
Related videos on Youtube
Andrew Bainbridge
Updated on August 31, 2020Comments
-
Andrew Bainbridge over 3 years
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? -
Ralph Sinsuat over 14 yearsI've used
ctypes
a few times and I've encountered it in the linked documentation before. -
Mike Vella almost 9 yearsWhy i it a
LP_c_ulong
object and notLP_c_ulong_Array_5
object -
Charles Grunwald over 7 years
LP_c_ulong_Array_5
would be an address pointing to an address pointing to the first element in an array ofuint32
s, whereas the OP's function is looking to receive an address pointing to the first element of an array.LP_c_ulong_Array_5
would be for a function like:int c_read_block(uint32 addr, uint32 *buf[], uint32 num);