Reputation: 41
I am trying to use a DLL file from python with ctypes but get stuck in a problem of
OSError: exception: access violation reading 0x00000000
The code is:
import ctypes as ctypes
NS = ctypes.oledll.LoadLibrary ("D:\\XXX\\nsga2.dll")
NS.Initialise(360,2,2,5,0,5,2)
NS.Randomise()
In DLL file, the function Randomise()
is defined as follow:
ADDAPI void
ADDCALL Randomise(){
randomize();
initialize_pop (parent_pop);
ngen = 0;}
And the function randomize()
is defined as:
# 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;
}
My question is why I get this problem and how can I fix it?
EDIT 1 as asked
The function Initialise()
is defined as:
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;
}
Upvotes: 2
Views: 10251
Reputation: 178021
The implementation of Initialise
isn't important, but the declaration is, including what ADDAPI
and ADDCALL
are defined as. Assuming ADDAPI
is something like __declspec(dllexport)
and ADDCALL
is __cdecl
(or empty), then use:
import ctypes
NS = ctypes.CDLL("D:\\XXX\\nsga2.dll")
NS.Initialise(360,2,2,5,0,5,2)
NS.Randomise()
Use ctypes.WinDLL
if ADDCALL
is __stdcall
.
Ideally, define argtypes
and restype
, but integer parameters are the default anyway, e.g.:
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
Upvotes: 0