我正在尝试将 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;
}
Initialise
的实现并不重要,重要的是声明,包括ADDAPI
和ADDCALL
的定义。假设 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()
如果
ctypes.WinDLL
是 ADDCALL
,则使用 __stdcall
。
理想情况下,定义
argtypes
和 restype
,但整数参数无论如何都是默认值,例如:
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