Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
526 views
in Technique[技术] by (71.8m points)

python - Error when using ctypes module to acess a 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 retuns a custom struct caled res 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've compiled it with 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 call the function with those values, it wil throw this to me:

WindowsError: exception: access violation writing 0x00000000

I also don't know how to catch the custom structure I declared and convert each of it's elements into Python floating points. I've looked into this PyDocs link but to no avail.

Thank you in advance.

EDIT:

This is the original (modified according to suggestions) 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, in case something might be wrong with it, the code file (it's very short, just 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;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There is a problem with returning structs like that. Not all compilers return such structures the same way. I'd 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);

That way the struct is in the user's memory, and there is no ambiguity on how the struct will be returned.

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...