How to pass an array to a shared library (.dll) written in c using python

function code of the test.dll file:

double __cdecl add(int len,double array[]){} 

(and I tested it in vc)

python code:

 import ctypes from ctypes import * N=... arr=(c_double*N)() ... ... dll=CDLL("test.dll") sum=dll.add(c_int(N),byref(arr)) print sum 

but python code doesn't work, and the "sum" is always N (for example, when N = 10, it prints "sum = 10") what is wrong with it?

+4
source share
2 answers

Array transfer in ctypes mirrors passing an array to C, i.e. you do not need to pass a reference to it, since the array is already a reference to its first element.

 from ctypes import * N = ... arr=(c_double*N)() dll=CDLL("test.dll") sum=dll.add(c_int(N),arr) print sum 

An example of this can be seen in the ctypes documentation in the section

+9
source

The problem here is that the function is defined as

 double __cdecl add(int len, double array[]) { } 

However, if you do not specify a return type for it, ctypes defaults to int . This is similar to declaring a function in C as

 int __cdecl add(int len, double array[]); 

Since the declaration and definition do not match, your code has undefined behavior, i.e.:

- A function is defined with a type that is incompatible with the type of (expression) that the expression denotes the function being called (6.5.2.2).


In this particular case, you work in an architecture where the values ​​of integers and floating point values ​​are returned to registers; however, the return values ​​of int and double are stored in different registers. Now the register containing the return value of type int in this ABI contains N as the remaining one. The correct return value was contained in the floating point register, however, it was never used because ctypes expected to get an int .

Therefore, the correct correction must be performed

 dll.add.restype = c_double 
0
source

Source: https://habr.com/ru/post/1403477/


All Articles