views:

379

answers:

1

Hey! as you might have noticed I have an annoying issue with ctypes. I'm trying to communicate with an instrument and to do so I have to use ctypes to communicate with the DLL driver.

so far I've managed to export the DLL by doing this:

>>> 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'

And it works pretty well, according to the documentation it is supposed to save the Tuner Driver DLL in the 80 byte string given as a parameter. However when I try to use the function called *add_tuner* it fails. This is what the documentation says:

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

this is how I tried to call the function above: The parameters that are changed are all the pointers and max_range[], according to the manual the values below are correct too, i just don't know why I keep getting a windows access violation writing 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))

The serial number is given however censored by refering to a variable. Someone know what to do?, do you see any errors with my input?

Thanks /Mazdak

+2  A: 

I figure it's the value you pass at the long max_range[] argument. The function expects a pointer to a long integer there (it asks for an array of long integers), but you're passing a long value of zero (result of the c_long() call), which is implicitly cast to a null pointer. I suspect the function then tries to write to the address passed at max_range, ie. the null pointer, hence the access violation at address 0x00000000.

To create an array of longs to pass in max_range, you first create the array type by multiplying the array data type with the size of the array (somewhat verbose for clarity):

array_size = 3
ThreeLongsArrayType = c_long * array_size

You can then instantiate an array like you would with any other Python class:

array = ThreeLongsArrayType()
Steef
Ow! that is true!, totally missed that one, that has to be it. So how do I declare an array with c_long()s?, is it arrayLong = c_long() * 3?Cause, when I change c_long to arrayLong it says that it don't know how to convert parameter 7(ctypes.argumentError)
I added an explanation about how to do that to my answer :)
Steef
Thanks! it worked perfectly, thank you for easing my pain =)