Python中的ctypes,调用DLL中的函数问题

0 投票
1 回答
2432 浏览
提问于 2025-04-15 12:15

嘿!你可能注意到了,我在使用ctypes的时候遇到了一个烦人的问题。我正在尝试和一个仪器进行通信,为此我需要用ctypes来和DLL驱动程序进行交流。

到目前为止,我已经通过以下方式成功导出了DLL:

>>> from ctypes import *
>>>maury = WinDLL( 'MLibTuners')
>>> maury
(WinDLL 'MlibTuners', handle 10000000 at 9ef9d0)
>>> maury.get_tuner_driver_version()
(_FuncPtr object at 0x009F6738)
>>> version_string = create_string_buffer(80)
>>> maury.get_tuner_driver_version(version_string)
2258920
>>> print version_string.value
'Maury Microwave MT993V04 Tuner Driver DLL, Version 1.60.00, 07/25/2007'

这工作得还不错,根据文档,它应该把调谐器驱动DLL保存在作为参数提供的80字节字符串中。不过,当我尝试使用一个叫做add_tuner的函数时,它失败了。文档上是这么说的:

short add_tuner(short tuner_number, char model[], short serial_number,
               short ctlr_num, short ctlr_port, short *no_of_motors, long max_range[],
               double *fmin, double *fmax, double *fcrossover, char error_string[])

这是我尝试调用上面那个函数的方式:改变的参数都是指针和max_range[],根据手册,下面的值也是正确的,只是我不知道为什么我总是遇到windows访问违规,写入0x00000000的错误。

no_motors = pointer(c_short())
f_min = pointer(c_double())
f_max = pointer(c_double())
f_crossover = pointer(c_double())
maury.add_tuner(c_short(0), c_char_p('MT982EU'), c_short(serial_number), c_short(0),
                                c_short(1),no_motors, c_long(),
f_min,f_max,f_crossover, create_string_buffer(80))

序列号是给出的,但通过一个变量进行了遮蔽。有人知道该怎么做吗?你们觉得我的输入有什么错误吗?

谢谢!

1 个回答

3

我觉得问题出在你传给 long max_range[] 这个参数的值上。这个函数其实是希望你传一个指向 long 整数的指针(也就是一个 long 整数的数组),但是你传的是一个值为零的长整型(这是 c_long() 调用的结果),这个零值被隐式地转换成了一个空指针。我猜这个函数接着试图写入你在 max_range 传入的地址,也就是这个空指针,所以就出现了在地址 0x00000000 的访问违规。

要创建一个 long 类型的数组来传给 max_range,你首先需要通过将数组数据类型和数组的大小相乘来创建数组类型(这样说可能有点啰嗦,但为了清楚起见):

array_size = 3
ThreeLongsArrayType = c_long * array_size

然后你可以像使用其他任何 Python 类一样实例化一个数组:

array = ThreeLongsArrayType()

撰写回答