“WindowsError:异常:访问冲突......” - ctypes的问题(“Window

2019-07-04 22:43发布

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

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

在另一个线程,我问了一下如何正确地创建和发送所需的参数给这个函数。

这里是螺纹: 我如何把这个包的C函数,使用多个参数,与ctypes的?

所以我用在上面的线程的好资料,但现在我得到这个错误:WindowsError:异常:访问冲突写0x00001001

我不能确定如何进行。 我在Windows XP上 - 如果我登录到管理员帐户,将是解决这一问题? 或者,这是Python的内存对象是不可变的问题吗?

谢谢大家!

编辑相关的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)

编辑补充一些相关的代码! 我只是写一个简单的脚本来获取每个设备的功能第一个工作日。 变量sizeTRACE可重复使用的,我知道,但现在它只是测试代码和设备未挂接,这样的getSize()将返回零。 乘以零会杀了我的嗡嗡声,所以我就强制为1现在。 如果这是不明确的,我道歉,并会尝试编辑这个职位。

第二个编辑:有人建议在设备堵塞,看看是否有帮助。 我刚刚插入的青蛙,但我仍然得到同样的错误。 很奇怪,我宁愿无能。 在任何情况下,再次感谢大家!

Answer 1:

你得到的错误是不相关的管理权限。 问题是你正在使用C和无意中执行非法操作(如果未选中去了可能会造成系统崩溃的那种操作)。

你得到的错误表明你的程序试图写入到内存地址1001,但不应该被写入到内存地址。

这可能发生在任何数量的原因。

一个可能的原因是,*你传递给ReturnPulse双不一样大,ReturnPulse预计的那样。 你可能需要至少得到的getSize正常工作......你也许能够通过只分配一个非常大的阵列,而不是调用的getSize解决它。 即

ptrfdP = (c_double*100000)()

这将拨款10万个双打,这可能是更适合捕捉数字脉冲。

另一个问题是,随着预期的类型转换可能不会发生。

如果ctypes的知道ReturnPulse需要五个指针你可能有更好的运气。 即

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

如果没有这些技术的工作原理,在发送的ReturnPulse使用文档,这将有助于我们认识用途。

或者更好的是,发送的应该在C工作示例代码,我会翻译,要在ctypes的等效实现。

编辑:添加ReturnPulse和ctypes的用法示例实现。

我已经实现的东西像什么,我希望ReturnPulse在一个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的用下面的代码调用它:

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

所得到的输出是

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,代码运行没有错误。



Answer 2:

ptrpulse和朋友蟒蛇标识符指向不同的ctypes对象(我猜他们都是c_double * 2)。 它们或者需要用一个ctypes指针对象被包裹,或传递给使用ctypes.byref C函数。



文章来源: “WindowsError: exception: access violation…” - ctypes question