ctypes em python, problema chamar uma função em uma DLL
Pergunta
Hey! como você deve ter notado que eu tenho um problema chato com ctypes. Eu estou tentando se comunicar com um instrumento e para isso eu tenho que usar ctypes para se comunicar com o driver DLL.
até agora eu consegui exportar a DLL, fazendo isso:
>>> 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'
E ele funciona muito bem, de acordo com a documentação que é suposto para salvar o DLL Tuner Driver na seqüência de 80 bytes dado como um parâmetro. No entanto, quando eu tento usar a função chamada add_tuner ele falhar. Isto é o que a documentação diz:
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[])
é assim que eu tentei chamar a função acima: Os parâmetros que são alterados são todos os ponteiros e max_range [], de acordo com o manual os valores abaixo estão corretos também, eu só não sei porque eu continuo recebendo um janelas de violação de acesso de escrita 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))
O número de série é dado no entanto censurado por referindo-se a uma variável. Alguém sabe o que fazer ?, você vê erros com a minha entrada?
Graças / Mazdak
Solução
Eu acho que é o valor que você passa no argumento long max_range[]
. A função espera um ponteiro para uma long
inteiro lá (ele pede para um array de inteiros long
), mas você está passando uma longa valor de zero (resultado da chamada c_long()
), que é implicitamente elenco a um ponteiro nulo. Eu suspeito que a função, em seguida, tenta escrever para o endereço passado pelo max_range
, ie. o ponteiro nulo, portanto, a violação de acesso no 0x00000000
endereço.
Para criar uma matriz de long
s passar em max_range
, você primeiro criar o tipo de matriz multiplicando o tipo de dados de matriz com o tamanho da matriz (um pouco detalhado para maior clareza):
array_size = 3
ThreeLongsArrayType = c_long * array_size
Você pode então instanciar uma matriz como você faria com qualquer outra classe Python:
array = ThreeLongsArrayType()