"WindowsError: exception: access violation ..." - ctypes question

Here is a prototype of the C function, which is in the DLL:

extern "C" void__stdcall__declspec(dllexport) ReturnPulse(double*,double*,double*,double*,double*); 

In another thread, I asked how to correctly create and send the necessary arguments to this function.

Here's the topic: How to port this C function with multiple arguments using ctypes?

So, I used good information in this thread, but now I get this error: WindowsError: exception: access violation record 0x00001001

I am not sure how to proceed. I am on Windows XP - if I log in to the administrator account, will this fix the problem? Or is this a problem with immutable Python memory objects?

Thanks everyone!

Edited using the appropriate Python:

 FROGPCGPMonitorDLL = windll.LoadLibrary('C:\Program Files\MesaPhotonics\VideoFROG 7.0\PCGPMonitor.dll') #Function argument:double* pulse sizePULSE = 2 ##Manual is super unclear here pulse = c_double * sizePULSE ptrpulse = pulse() #Function argument:double* tdl sizeTRACE = FROGPCGPMonitorDLL.GetSize() if sizeTRACE == 0 : sizeTRACE = 1 #Manually set size to 1 for testing purposes print "Size of FROG trace is zero. Probably not right." tdl = c_double*sizeTRACE ptrtdl = tdl() #Function argument:double* tdP sizeTRACE = FROGPCGPMonitorDLL.GetSize() if sizeTRACE==0: sizeTRACE=1 print "Size of FROG trace is zero. Probably not right." tdP = c_double*sizeTRACE ptrtdP = tdP() #Function Argument:double* fdl sizeTRACE = FROGPCGPMonitorDLL.GetSize() if sizeTRACE==0: sizeTRACE=1 print "Size of FROG trace is zero. Probably not right." fdl = c_double*sizeTRACE ptrfdl = fdl() #Function Argument: double* fdP sizeTRACE = FROGPCGPMonitorDLL.GetSize() if sizeTRACE==0: sizeTRACE=1 print "Size of FROG trace is zero. Probably not right." fdP = c_double*sizeTRACE ptrfdP = fdP() FROGPCGPMonitorDLL.ReturnPulse(ptrpulse, ptrtdl, ptrtdP,ptrfdl,ptrfdP) 

Edited to add the appropriate code! I am just writing a simple script to work with each of the device functions first. The sizeTRACE variable can be reused, I know, but its just a test code right now, and the device is not connected, so GetSize () returns zero. Multiplying by zero will kill my buzz, so I force it so far 1. If this is not clear, I apologize and try to edit this message.

Second edit: It was suggested to connect the device and see if it helped. I just hooked up FROG, but I still get the same error. Very strange, and I'm pretty ignorant. Anyway, thanks again everyone!

+4
source share
2 answers

The error you are getting is not related to admin rights. The problem is that you use C and inadvertently perform illegal operations (a type of operation that, if left unchecked, is likely to crash your system).

The error you received indicates that your program is trying to write to memory address 1001, but should not write to this memory address.

This can happen for a number of reasons.

One possible reason is that the double * you pass to ReturnPulse is not as big as ReturnPulse. You probably need to at least get GetSize to work correctly ... you could get around it by simply allocating a very large array instead of calling GetSize. i.e.

 ptrfdP = (c_double*100000)() 

This will give out 100,000 doubles, which may be more suitable for capturing a digital pulse.

Another problem is that type conversion may not occur as expected.

You might be lucky if ctypes knows that ReturnPulse accepts five double pointers. i.e.

 # sometime before calling ReturnPulse FROGPCGPMonitorDLL.ReturnPulse.argtypes = [POINTER(c_double), POINTER(c_double), POINTER(c_double), POINTER(c_double), POINTER(c_double)] 

If none of these methods work, send the usage documentation to ReturnPulse, which should help us recognize the intended use.

Or even better, send an example of code that should work in C, and I will translate it into an equivalent implementation in ctypes.

Edit: Add an example implementation using ReturnPulse and ctypes.

I implemented something like what I expect from ReturnPulse in the C DLL:

 void ReturnPulse(double *a, double*b,double*c,double*d,double*e) { // write some values to the memory pointed-to by ae // ae should have enough memory allocated for the loop for(int i = 0; i < 20; i++) { a[i] = 1.0*i; b[i] = 3.0*i; c[i] = 5.0*i; d[i] = 7.0*i; e[i] = 13.0*i; } } 

I compile this in a DLL (I call examlib) and then call it with ctypes with the following code:

 LP_c_double = ctypes.POINTER(ctypes.c_double) examlib.ReturnPulse.argtypes = [LP_c_double, LP_c_double, LP_c_double, LP_c_double, LP_c_double, ] a = (ctypes.c_double*20)() b = (ctypes.c_double*20)() c = (ctypes.c_double*20)() d = (ctypes.c_double*20)() e = (ctypes.c_double*20)() examlib.ReturnPulse(a,b,c,d,e) print 'values are' for array in (a,b,c,d,e): print '\t'.join(map(str, array[:5])) 

Result result

 values are 0.0 1.0 2.0 3.0 4.0 0.0 3.0 6.0 9.0 12.0 0.0 5.0 10.0 15.0 20.0 0.0 7.0 14.0 21.0 28.0 0.0 13.0 26.0 39.0 52.0 

Indeed, even without setting ReturnPulse.argtypes, the code works without errors.

+12
source

ptrpulse and friends are python identifiers that point to various ctypes objects (I think they are all c_double * 2). They must either be wrapped with a ctypes pointer object, or passed to the C function using ctypes.byref.

0
source

All Articles