Python Ctypes OSError:异常:访问冲突读取0x00000000

Posted

技术标签:

【中文标题】Python Ctypes OSError:异常:访问冲突读取0x00000000【英文标题】:Python Ctypes OSError: exception: access violation reading 0x00000000 【发布时间】:2019-06-19 00:13:58 【问题描述】:

我正在尝试将 python 中的 DLL 文件与 ctypes 一起使用,但遇到了

的问题

OSError:异常:访问冲突读取 0x00000000

代码是:

import ctypes as ctypes
NS = ctypes.oledll.LoadLibrary ("D:\\XXX\\nsga2.dll")
NS.Initialise(360,2,2,5,0,5,2)
NS.Randomise()

在DLL文件中,函数Randomise()定义如下:

ADDAPI  void
ADDCALL Randomise()
randomize();
initialize_pop (parent_pop);
ngen = 0;

而函数randomize()定义为:

 # include "rand.h"
   double seed;
   double oldrand[55];
   int jrand;
   void randomize()
   
       int j1;
       for(j1=0; j1<=54; j1++)
       
          oldrand[j1] = 0.0;
       
       jrand=0;
       warmup_random (seed);
       return;
   

我的问题是为什么我会遇到这个问题,我该如何解决?

谢谢大家!

按要求编辑 1

函数Initialise()定义为:

ADDAPI  void 
ADDCALL Initialise(int populationSize, int objectives, int constraints,  
int realvars, int binvars, int intvars, int nfix)

    popsize = populationSize;
    nobj = objectives;
    ncon = constraints;
    nreal = realvars;
    nint = intvars;
    nbin = binvars;
    nfixed = nfix;

    nbits = (int *)malloc(binvars*sizeof(int));
    for (int i = 0 ; i <binvars  ; i++)
        
            nbits[i]=24 ;
         

    nints = (int *)malloc(nint*sizeof(int));
    bints = (int *)malloc(nint*sizeof(int));    

    for (int i = 0 ; i <nfixed/(2*nswitch+1); i++) 
        
                bints[i*(2*nswitch+1)]=0; 
                nints[i*(2*nswitch+1)]=1; 
                //nints[i*(2*nswitch+1)]=2;

                 for (int j =(2*nswitch+1)*i+1 ; j<(2*nswitch+1)*(i+1); i++) 

                 
                    bints[j]=0; 
                    nints[j]=TimeLength; 
                    //nints[j]=25;
                
        

    min_realvar = (double *)malloc(nreal*sizeof(double));
    max_realvar = (double *)malloc(nreal*sizeof(double));

    intvar = NULL;
    min_binvar = NULL;
    max_binvar = NULL;

    parent_pop = (population *)malloc(sizeof(population));
    child_pop = (population *)malloc(sizeof(population));
    mixed_pop = (population *)malloc(sizeof(population));

     allocate_memory_pop (parent_pop, popsize);
     allocate_memory_pop (child_pop, popsize);
     allocate_memory_pop (mixed_pop, 2*popsize);

     seed = 0.232; // for random functions

     bitlength = 0;
     pcross_bin = 0;
     pcross_int = 0;
     pmut_bin = 0 ;
     pmut_int = 0;
     eta_c = 50 ; // distribution index for crossover
     eta_m = 100 ; // distrubution index for mutations
     nbits = 0 ;
     nints = 0;

     fitness_func = NULL;
 

【问题讨论】:

哪个函数抛出错误?也请张贴初始化 函数抛出错误是 NS.Randomise() 我尝试在 DLL 中调用 Ranmosie() 函数。 初始化也贴在上面 那是 InitialiseRandomiseWithFile。但无论如何,问题变得清晰了,它是导入函数的 argtypes(和 restype)定义。 Initialise 是失败的函数。这与***.com/questions/52268294/… 或***.com/questions/53182796/… 的问题相同。我会将这个问题标记为其他问题的重复。 python ctypes issue on different OSes的可能重复 【参考方案1】:

Initialise 的实现并不重要,但 声明 很重要,包括 ADDAPIADDCALL 的定义。假设ADDAPI 类似于__declspec(dllexport)ADDCALL__cdecl(或空),然后使用:

import ctypes
NS = ctypes.CDLL("D:\\XXX\\nsga2.dll")
NS.Initialise(360,2,2,5,0,5,2)
NS.Randomise()

如果ADDCALL__stdcall,则使用ctypes.WinDLL

理想情况下,定义argtypesrestype,但无论如何整数参数都是默认值,例如:

NS.Initialise.argtypes = ctypes.c_int,ctypes.c_int,ctypes.c_int,ctypes.c_int,ctypes.c_int,ctypes.c_int,ctypes.c_int
NS.Initialise.restype = None
NS.Randomise.argtypes = ()
NS.Randomise.restype = None

【讨论】:

嗨,马克,感谢您的回复。我认为对于这种情况,它应该使用 ctypes.WinDLL 。而且我还添加了您上面提到的这些类型的说明,但遗憾的是,当我调用 Randomise()... 时我仍然遇到相同的错误 @ZZG 只有整数参数,唯一可以真正搞砸的是调用约定。您使用的是 32 位 Python 吗? WinDLL/CDLL 在 64 位上没有区别,但在 32 位上,您必须使用正确的,否则可能会发生您所看到的崩溃。你试过 CDLL 吗? ADDCALL 和 ADDAPI 解析为什么?

以上是关于Python Ctypes OSError:异常:访问冲突读取0x00000000的主要内容,如果未能解决你的问题,请参考以下文章

ctypes,python3.5,OSError:异常:访问冲突写入 0x00000000

PYTHON - Ctypes:OSError:异常:访问冲突写入0xFFFFFFFFFA1C001B

ctypes:OSError:异常:访问冲突读取0x00000001

从 Python 访问 errno?

WindowsError 异常访问冲突 - 在简单的 python c++ ctypes 接口中

如何捕获ctypes中抛出的异常?