Error using ctypes module to access dll written in C

I have a DLL with one single function that gets five doubles and one int:

__declspec(dllexport) struct res ITERATE(double z_r,double z_i,double c_r, double c_i, int iterations, double limit) 

It reconfigures the custom structure, which consists of a three-double array:

 struct res { double arr[3]; }; 

To return the values, I do this:

 struct res result; /*earlier in the code */ result.arr[0] = z_real; /*Just three random doubles*/ result.arr[1] = z_imag; result.arr[2] = value; return result; 

I compiled it using MinGW, and I'm trying to use it in python to do something like this:

 form ctypes import * z = [0.0,0.0] c = [1.0,1.0] M = 2.0 MiDLL = WinDLL("RECERCATOOLS.dll") MiDLL.ITERATE.argtypes = [c_double, c_double, c_double, c_double,c_int,c_double] MiDLL.ITERATE(z[0],z[1],c[0],c[1],100,M) #testing out before assigning the result to anything. 

But, whenever I try to call a function with these values, it will throw me:

 WindowsError: exception: access violation writing 0x00000000 

I also don’t know how to catch the custom structure that I declared and convert each of its elements to Python floating points. I looked at this PyDocs link , but to no avail.

Thanks in advance.

EDIT:

This is the original (modified as suggested) header used ("mydll.h"):

 #ifndef MYDLL_H #define MYDLL_H extern "C" __declspec(dllexport) #define EXPORT_DLL __declspec(dllexport) EXPORT_DLL void ITERATE(struct res*, double z_r,double z_i,double c_r, double c_i, int iterations, double limit) #endif 

And, if something may be wrong with it, the code file (it is very short, only one function):

 #include <stdio.h> #include <complex.h> struct res { double arr[3]; }; void __declspec(dllexport) ITERATE(struct res* result,double z_r,double z_i,double c_r, double c_i, int iterations, double limit) { /* The purpose of this function is, given two complex numbers, an iteration number and a limit, apply a formula to these two numbers for as many iterations as specified. If at any iteration the result of the formula is bigger than the limit, stop and return the number and the iteration it reached. If after iterating they are still inside the limit, return the number after all the iterations and the number of iterations it has gone through. Complex numbers are composed of a real part and an imaginary part, and they must be returned separately. */ double complex z = z_r + z_i*I; double complex c = c_r + c_i*I; int actual_iter; for (actual_iter = 1; actual_iter <= iterations; actual_iter++) { z = z*z + c; if (cabs(z) > limit) { double value = actual_iter; double z_real = creal(z); double z_imag = cimag(z); result.arr[0] = z_real; result.arr[1] = z_imag; result.arr[2] = value; } } double value = iterations; double z_real = creal(z); double z_imag = cimag(z); result.arr[0] = z_real; result.arr[1] = z_imag; result.arr[2] = value; } int main() { return 0; } 
+1
source share
1 answer

There is a problem with the return of such structures. Not all compilers return such structures the same way. I would rather change the function declaration to this:

 void __declspec(dllexport) ITERATE(struct res* result, double z_r,double z_i, double c_r, double c_i, int iterations, double limit); 

Thus, the structure is in user memory, and there is no ambiguity as to how the structure will be returned.

Of course, as David said, you may have to use a different agreement.

+2
source

All Articles