“WindowsError:异常:访问冲突……"- ctypes 问题 [英] "WindowsError: exception: access violation..." - ctypes question

查看:39
本文介绍了“WindowsError:异常:访问冲突……"- ctypes 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是驻留在 DLL 中的 C 函数的原型:

Here is the prototype for a C function that resides in a DLL:

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

在另一个线程中,我询问了如何正确地创建并向该函数发送必要的参数.

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

这里是线程:我如何包装这个 C 函数,有多个参数,有 ctypes?

所以我使用了上面线程中的好信息,但现在我收到了这个错误:WindowsError:异常:访问冲突写入 0x00001001

So I have used the good information in the thread above, but now I am getting this error: WindowsError: exception: access violation writing 0x00001001

我不确定如何继续.我使用的是 Windows XP - 如果我登录管理员帐户,是否可以解决问题?或者这是 Python 的内存对象不可变的问题?

I am unsure as to how to proceed. I'm on Windows XP - if I log into the administrator account, would that fix the problem? Or is this a problem with Python's memory objects being immutable?

谢谢大家!

使用相关 Python 进行

FROGPCGPMonitorDLL = windll.LoadLibrary('C:Program FilesMesaPhotonicsVideoFROG 7.0PCGPMonitor.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)

编辑添加一些相关代码!我只是在编写一个简单的脚本来让设备的每个功能首先工作.变量 sizeTRACE 可以重复使用,我知道,但它现在只是测试代码,设备没有连接,所以 GetSize() 返回零.乘以零会扼杀我的嗡嗡声,所以我现在将其强制为 1.如果这不是很清楚,我很抱歉,并会尝试编辑这篇文章.

Edited to add some relevant code! I'm just writing a simple script to get each of the device's functions working first. The variable sizeTRACE can be reused, I know, but its just test code right now and the device isn't hooked up, so GetSize() is returning zero. Multiplying by zero would kill my buzz, so I'm forcing it to 1 for now. If this isn't clear, I apologize and will try to edit this post.

第二次建议插入设备,看看是否有帮助.我刚刚插入了 FROG,但我仍然遇到同样的错误.很奇怪,我很无知.无论如何,再次感谢大家!

Second edit: It was suggested to plug in the device and see if that helped. I just plugged in the FROG, but I'm still getting the same error. Very strange, and I'm rather clueless. In any event, thanks again all!

推荐答案

您遇到的错误与管理权限无关.问题是您在使用 C 并无意中执行了非法操作(如果不加以检查的操作类型可能会使您的系统崩溃).

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).

您得到的错误表明您的程序正在尝试写入内存地址 1001,但不应该写入该内存地址.

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.

一个可能的原因是您传递给 ReturnPulse 的 double* 没有 ReturnPulse 预期的那么大.您可能至少需要让 GetSize 正常工作……您可以通过分配一个非常大的数组而不是调用 GetSize 来解决它.即

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)()

这将分配 100,000 个双精度值,这可能更适合捕获数字脉冲.

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.

如果 ctypes 知道 ReturnPulse 需要五个双指针,您可能会更幸运.即

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)]

如果这些技术都不起作用,请将使用文档发送到 ReturnPulse 上,这应该有助于我们识别预期用途.

If neither of these techniques works, send the usage documentation on ReturnPulse, which should help us recognize the intended use.

或者更好的是,发送应该在 C 中工作的示例代码,我会将其转换为 ctypes 中的等效实现.

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

添加 ReturnPulse 和 ctypes 用法的示例实现.

adding example implementation of ReturnPulse and ctypes usage.

我已经实现了一些类似于我期望 ReturnPulse 在 C DLL 中执行的操作:

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;
    }
}

我将它编译成一个 DLL(我称之为 examlib),然后使用 ctypes 和以下代码调用它:

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 '	'.join(map(str, array[:5]))

结果输出是

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

事实上,即使没有设置 ReturnPulse.argtypes,代码运行也不会出错.

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

这篇关于“WindowsError:异常:访问冲突……"- ctypes 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆