“ WindowsError:例外:访问冲突...” -ctypes问题 [英] "WindowsError: exception: access violation..." - ctypes question

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

问题描述

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

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

在另一个线程中,我询问如何正确创建并将必要的参数发送到此函数。 / p>

这里是线程:



因此,如何使用多个参数将C函数包装为ctypes?

我已经在上面的线程中使用了很好的信息,但是现在我收到此错误:
WindowsError:异常:访问冲突写入0x00001001



我不确定如何进行。我使用的是Windows XP-如果我登录管理员帐户,是否可以解决问题?还是这与Python的内存对象不可变有关?



谢谢!



相关的Python:

  FROGPCGPMonitorDLL = windll.LoadLibrary('C:\Program Files\MesaPhotonics\VideoFROG 7.0\PCGPMonitor.dll')

#函数参数:double * pulse
sizePULSE = 2 ##此处的手册非常不清楚
pulse = c_double * sizePULSE
ptrpulse = pulse()

#函数参数:double * tdl
sizeTRACE = FROGPCGPMonitorDLL.GetSize()
(如果sizeTRACE == 0:
sizeTRACE = 1#手动为测试目的,将大小设置为1
打印 FROG跟踪的大小为零。可能不正确。
tdl = c_double * sizeTRACE
ptrtdl = tdl()


#函数参数:double * tdP
sizeTRACE = FROGPCGPMonitorDLL.GetSize()$ b 如果sizeTRACE == 0,则为$ b:
sizeTRACE = 1
打印 FROG跟踪的大小为零。可能不正确。
tdP = c_double * sizeTRACE
ptrtdP = tdP()


#函数参数:double * fdl
sizeTRACE = FROGPCGPMonitorDLL.GetSize()$ b 如果sizeTRACE == 0,则为$ b:
sizeTRACE = 1
打印 FROG跟踪的大小为零。可能不正确。
fdl = c_double * sizeTRACE
ptrfdl = fdl()

#函数参数:double * fdP
sizeTRACE = FROGPCGPMonitorDLL.GetSize()
如果sizeTRACE == 0:
sizeTRACE = 1
打印 FROG跟踪的大小为零。可能不正确。
fdP = c_double * sizeTRACE
ptrfdP = fdP()

FROGPCGPMonitorDLL.ReturnPulse(ptrpulse,ptrtdl,ptrtdP,ptrfdl,ptrfdP)

编辑后添加了一些相关代码!
我只是在编写一个简单的脚本,以使每个设备的功能先运行。我知道,变量sizeTRACE可以重用,但是它现在只是测试代码,并且没有连接设备,因此GetSize()返回零。乘以零会杀死我的嗡嗡声,因此我暂时将其设为1。如果不清楚,我表示歉意,并将尝试编辑此帖子。



第二次编辑:
建议插入设备,看看是否有帮助。我只是插入了FROG,但仍然遇到相同的错误。非常奇怪,我一无所知。无论如何,再次感谢所有人!

解决方案

您得到的错误与管理权限无关。问题是您正在使用C并无意中执行了非法操作(如果不检查这些操作可能会导致系统崩溃)。



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



这种情况可能有多种原因。

p>

一个可能的原因是,您传递给ReturnPulse的double *不如ReturnPulse期望的那么大。您可能至少需要使GetSize正常工作...您可能可以通过分配一个非常大的数组而不是调用GetSize来解决此问题。即

  ptrfdP =(c_double * 100000)()

这将分配100,000个double,这可能更适合捕获数字Pulse。



另一个问题是



如果ctypes知道ReturnPulse需要五个双指针,则可能会更好。例如,

 #在调用ReturnPulse 
FROGPCGPMonitorDLL之前的某个时间。ReturnPulse.argtypes= [POINTER(c_double),POINTER(c_double) ,POINTER(c_double),POINTER(c_double),POINTER(c_double)]

可以,请在ReturnPulse上发送用法文档,这应该有助于我们识别预期的用法。



或者更好的是,发送应该在C中工作的示例代码,我将



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



我已经实现了我期望ReturnPulse在C DLL中执行的操作:

  void ReturnPulse(double * a,double * b,double * c,double * d,double * e)
{
//将一些值写入ae指向的内存
// ae应该为循环
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(我称它为EXliblib ),然后使用带有以下代码的ctypes调用它:

  LP_c_double = ctypes.POINTER(ctypes.c_double)
exelib.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)()

exelib.ReturnPulse(a,b,c,d,e)

打印'values'是
,用于(a,b,c,d,e)中的数组:
打印'\t'.join(map(str,array [:5]))

结果输出为

 值是
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

事实上,前夕n无需设置ReturnPulse.argtypes,代码即可正常运行。


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.

Here is the thread: How do I wrap this C function, with multiple arguments, with ctypes?

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

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?

Thanks all!

Edited with relevant 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 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.

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!

解决方案

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.

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

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