当前位置: 首页 > 面试题库 >

使用ctypes模块访问用C编写的DLL时出错

商华藏
2023-03-14
问题内容

我有一个带有一个单一函数的DLL,它具有五个双精度和一个整数:

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

它重新调整了由三重数组组成的自定义结构计算的res:

struct res {
   double arr[3];
};

要返回值,我这样做:

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;

我已经用MinGW对其进行了编译,并且试图在python中使用它来执行以下操作:

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.

但是,每当我尝试使用这些值调用函数时,都会将其抛出:

WindowsError: exception: access violation writing 0x00000000

我也不知道如何捕获我声明的自定义结构并将其每个元素转换为Python浮点数。我研究了这个PyDocs链接,但无济于事。

先感谢您。

编辑:

这是使用的原始(根据建议进行修改)标头(“ 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

并且,如果代码可能有问题,那么代码文件(它很短,只有一个函数):

#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;
}

问题答案:

像这样返回结构存在问题。并非所有的编译器都以相同的方式返回此类结构。我宁愿将函数声明更改为:

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

这样,该结构就在用户的内存中,并且对如何返回该结构也没有歧义。

当然,正如David所说,您可能必须使用其他调用约定。



 类似资料:
  • 问题 你有一些C函数已经被编译到共享库或DLL中。你希望可以使用纯Python代码调用这些函数, 而不用编写额外的C代码或使用第三方扩展工具。 解决方案 对于需要调用C代码的一些小的问题,通常使用Python标准库中的 ctypes 模块就足够了。 要使用 ctypes ,你首先要确保你要访问的C代码已经被编译到和Python解释器兼容 (同样的架构、字大小、编译器等)的某个共享库中了。 为了进行

  • 问题内容: 我正在寻找一个示例代码,该示例代码如何从用C编写的dll中导入等效于的 函数。这是可能的?我正在使用Windows。任何帮助表示赞赏。提前致谢。 问题答案: 您想使用cgo。这是介绍。

  • 最近我安装了Composer,因为它是安装Yii框架的首选方式,但我似乎无法使用它,我不知道为什么。 这是使用composer命令时发生的一个示例:C:\wamp\www

  • 问题内容: 我正在第一个NPM模块上工作。之前,我曾短暂地使用过Typescript,但一个大问题是,对于许多模块,没有可用的定义文件。因此,我认为用打字稿编写模块是一个好主意。 但是,我找不到有关最佳方法的任何信息。我发现了一个相关的问题“ 我可以在coffeescript中编写npm软件包吗? ”,那里的人们建议只发布javascript文件。但是与coffeescript文件相比,如果在打字

  • 本文向大家介绍易语言模块的编写和使用,包括了易语言模块的编写和使用的使用技巧和注意事项,需要的朋友参考一下 1.“模块:” 和其他语言的“类库”意思差不多,就是把一些常用的固定的方法(API)封装到“模块”中去,达到一次编译,多次调用的目的。 2.编写-打包-调用:(window开发) 1. 步骤:新建》window易语言模块》编写子程序; 2. 注意事项:不要随便修改编译器自动生成的一些参数;

  • 问题内容: 在带有Python 2.7的Windows 7上可以正常工作: 库prov_means.DLL在我的工作目录中。它导出没有依赖关系的简单,独立的C函数provmeans()。 当我在Windows XP和Python 2.7上尝试相同的操作时,我得到了 我尝试将DLL复制到Windows \ System32,并且还输入完整路径名 具有和不具有“ .DLL”扩展名。没事。 问题答案: