0

I have a numpy array that I need to get to a dll function wrapped in ctypes.

myFunc.argtypes = (...POINTER(ctypes.c_double),POINTER(ctypes.c_double),...)
myFunc(...Data1_arr,Data2_arr...)

I'm defining arrays like this and it works great. its just slow. 1.5ms for a small set of data

#these are c_double_array types
Data1_arr = (ctypes.c_double * len(Data1))(*Data1)
Data2_arr = (ctypes.c_double * len(Data2))(*Data2)

I found several ways to operate on the numpy arrays more directly, which are much faster. average 6.899999999809836e-06 seconds

#these are .LP_c_double types
Data1_ptr = Data1.ctypes.data_as(ctypes.POINTER(ctypes.c_double))
Data2_ptr = Data2.ctypes.data_as(ctypes.POINTER(ctypes.c_double))

The Data1_ptr._arr values match the Data1_arr values obviously.

MyFunc() even happily takes the Data1_ptr and Data2_ptr values. However, the output of the function is all messed up. MyFunc is obviously interpreting the c_double_array correctly, but not the LP_c_double.

I'll admit I'm punching over my weight here, but I am trying to learn.

Is there a way to get the c_double_array from the LP_c_double pointer without wasting extra time?

edit to add this: here is the C header

Proc_WriteData
(
   int32        DataLength,
   const double Data1[],
   const double Data2[]
);

Python calling it:

def Write_New_Data(Data1,Data2):

    dll.Proc_WriteData.argtypes = (int32,POINTER(ctypes.c_double),POINTER(ctypes.c_double))

    Data_Length = len(Data1)
    Data1_ptr = Data1.ctypes.data_as(ctypes.POINTER(ctypes.c_double))
    Data2_ptr = Data2.ctypes.data_as(ctypes.POINTER(ctypes.c_double))

    dll.Proc_WriteData(Data_Length, Data1_ptr, Data2_ptr)

I did see something like this. I tried it, but the output of the function was identical to the above.

return np.ctypeslib.ndpointer(dtype=element_type, shape=(dim,), flags="F_CONTIGUOUS")

Im now wondering about const double im wondering if thats where im getting stuck?

Please let me know if you need any more information. thanks

pyNewbie
  • 155
  • 1
  • 2
  • 10
  • Show the *C* function header. and the *Python* code calling it (**[\[SO\]: How to create a Minimal, Reproducible Example (reprex (mcve))](https://stackoverflow.com/help/minimal-reproducible-example)**). [\[SO\]: How to run a Fortran script with ctypes? (@CristiFati's answer)](https://stackoverflow.com/a/75944691/4788546), [\[SO\]: Sending numpy array (image) to c++ library with ctypes (@CristiFati's answer)](https://stackoverflow.com/a/73926710/4788546). – CristiFati Jul 12 '23 at 03:50
  • updated with new information. not sure how SO notifications work, so adding a comment here. – pyNewbie Jul 12 '23 at 12:39
  • It's still not clear what the problem is. Is there an error message? Is the .dll written in *Fortran*? There is no *MCVE* here. – CristiFati Jul 12 '23 at 13:49
  • dll is vendor provided. Data gets put out on hardware. Signal coming out is not correct. Using Data1_arr = (ctypes.c_double * len(Data1))(*Data1), i get the correct output. Using 'Data1_ptr = Data1.ctypes.data_as(ctypes.POINTER(ctypes.c_double))', i get the incorrect output. No errors, just incorrect output. At the end of the day, i would love to be able to access the data @.LP_c_double and pass it in just like the c_double_array. Im very green at this, so im sorry if thats a stupid question. Seems like the c_double_array is creating a copy of data array vs id love to just pass by ref? – pyNewbie Jul 12 '23 at 15:01
  • Also, i would love to include sample of (non)-working code, but cant include dll. is there a way to use a fake dll for demo purposes? again, im very green. – pyNewbie Jul 12 '23 at 16:35
  • Well, i figured this out yesterday. This (Data1_arr = (ctypes.c_double * len(Data1))(*Data1)) is creating floats, which evidently, the hardware likes. So, i made sure the the data is type float prior to calling this(Data1_ptr = Data1.ctypes.data_as(ctypes.POINTER(ctypes.c_double))). and then everything worked as expected and much faster. I appreciate your help guys! – pyNewbie Jul 14 '23 at 03:55

0 Answers0