“WindowsError: exception: access violation…” - ctypes question

喜欢而已 提交于 2019-11-28 00:18:46

The error you're getting is not related to Administrative rights. The problem is you're using C and inadvertently performing illegal operations (the kind of operations that if went unchecked would probably crash your system).

The error you get indicates that your program is trying to write to memory address 1001, but isn't supposed to be writing to that memory address.

This could happen for any number of reasons.

One possible reason is that the double* you're passing to ReturnPulse aren't as big as ReturnPulse expects them to be. You probably need to at least get GetSize to work properly... you might be able to work around it by just allocating a very large array instead of calling GetSize. i.e.

ptrfdP = (c_double*100000)()

That will allocate 100,000 doubles, which may be more appropriate for capturing a digital Pulse.

The other issue is that the type conversion may not be happening as expected.

You might have better luck if ctypes knows that ReturnPulse takes 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 neither of these techniques works, send the usage documentation on ReturnPulse, which should help us recognize the intended use.

Or better yet, send sample code that's supposed to work in C and I'll translate that to the equivalent implementation in ctypes.

Edit: adding example implementation of ReturnPulse and ctypes usage.

I have implemented something like what I expect ReturnPulse to be doing in a C DLL:

void ReturnPulse(double *a, double*b,double*c,double*d,double*e)
{
    // write some values to the memory pointed-to by a-e
    // a-e 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 into a DLL (which I call examlib), and then call it using 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]))

The resulting output is

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 runs without errors.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!