0

A DLL provides a pointer to a 1D array in my C code like this:

__int16 *data = Msg_RowAt(surfaceMsg, rowIdx);

//access the values like this
data[iterator]

I'm building a Python project where I need to access the values of the same array. I've tried the following but get an access violation when I try iterate surfaceData.

surfaceDataPtr = Msg_RowAt(surfaceMsg, row)
ptr = ctypes.POINTER(ctypes.c_int16)
surfaceData = ctypes.cast(surfaceDataPtr, ptr)
print("ptr: " + str(surfaceData))
print("val: " + str(surfaceData[1]))

I'm accessing the wrong memory location but I'm not too sure what I've done wrong. Can anyone see what I'm doing wrong?

  • 1
    You probably want to define the argument and return types of `Msg_RowAt` using `argtypes` and `restype`. – 101 Feb 04 '21 at 22:41
  • Casting after the fact is too late. 64-bit pointers are truncated because the default return type is c_int. Define .argtypes and .restype. – Mark Tolonen Feb 05 '21 at 07:06
  • [\[SO\]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer)](https://stackoverflow.com/questions/58610333/c-function-called-from-python-via-ctypes-returns-incorrect-value/58611011#58611011). – CristiFati Feb 05 '21 at 13:13

1 Answers1

1

You can define restype:

c.Msg_RowAt.restype = ctypes.POINTER(ctypes.c_int16)
surfaceDataPtr = Msg_RowAt(surfaceMsg, row)

Then, you can randomly access to each element:

print(surfaceDataPtr[0])
print(surfaceDataPtr[1])
...
ghchoi
  • 4,812
  • 4
  • 30
  • 53
  • Thanks for the examples. I didn't really understand how to implement the restype. – Velveteen_Brownie Feb 08 '21 at 17:03
  • @Velveteen_Brownie Nothing to implement. Python is not typed. You just assign what `restype` will be. In this case, Python should know `surfaceDataPtr` will be a C pointer to `short` variable. – ghchoi Feb 08 '21 at 17:05