Найти - Пользователи
Полная версия: Проблема с dll
Начало » Python для новичков » Проблема с dll
1
razr
пишу программу для цифрового 4канального вольтметра (k8047d). использую для этого библиотеку k8047d.dll взятую с сайта производителя (ну и еще вдовесок файлы fasttime32.dll и k8047e.exe, которые нужны для работы k8047d.dll).
в k8047d.dll есть 6 функций:
1) StartDevice()
2) StopDevice()
3) LEDon() - включает лампочку на вольтметре
4) LEDoff() - выключает лампочку на вольтметре
5) SetGain(Channel, Gain) - устанавливает максимальное напряжение (Gain), которое можно подключить к каналу (Channel). Channel может принимать значения 1..4, Gain - 1,2,5,10.
6) ReadData(Buffer) - возвращает массив из 8 элементов. два первых - отвечают за таймер, 4 следующих за напряжение на каналах, а два последних - хз за что (они не нужны)

так вот StartDevice(), StopDevice(), LEDon() и LEDoff() работают.

теперь первый вопрос: при вызове SetGain() вылазит ошибка, хотя вроде правильно всё указываю:
>>> from ctypes import *
>>> lib=cdll.k8047d
>>> lib.StartDevice()
33
>>> lib.SetGain(3,5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Procedure called with not enough arguments (8 bytes missing) or wrong calling convention
и второй: не пойму как получить и работать со значениями ReadData(). вот пример работы с этой функцией на Delphi (взят из описания dll'ки):
var  // global variables  
DataBuffer: ARRAY[0..7] OF Integer;

procedure TForm1.Button1Click(Sender: TObject);
var p:pointer;
i:integer;
s:string;
begin
p:=@DataBuffer; // Address of the data buffer
ReadData(p); // Read the data from K8047
memo1.clear;
s:='';
for i:=0 to 7 do s:=s +inttostr(DataBuffer[i]+chr(9);
memo1.lines.add(s); // Display the data
end;
razr
попробовал в SetGain использовать windll вместо cdll:
>>> from ctypes import *
>>> lib=windll.k8047d
>>> lib.StartDevice()
>>> lib.SetGain(1,1)
0
вроде теперь ошибку не выдает. правда не узнаю правильно ли это работает, пока не разберусь с ReadData()
pyuser
razr
… правда не узнаю правильно ли это работает, пока не разберусь с ReadData()
если я ничего не путаю, то выглядеть это будет примерно так
from ctypes import *

HEAP_ZERO_MEMORY = 8L

GetProcessHeap = windll.kernel32.GetProcessHeap
HeapAlloc = windll.kernel32.HeapAlloc
HeapFree = windll.kernel32.HeapFree

buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 8 * sizeof(c_int))

ReadData(buffer)

result = (c_int * 8).from_address(buffer)

# result - массив целых, делаем, что надо и освобождаем память
HeapFree(GetProcessHeap(), 0, buffer)
razr
pyuser
razr
… правда не узнаю правильно ли это работает, пока не разберусь с ReadData()
если я ничего не путаю, то выглядеть это будет примерно так
from ctypes import *

HEAP_ZERO_MEMORY = 8L

GetProcessHeap = windll.kernel32.GetProcessHeap
HeapAlloc = windll.kernel32.HeapAlloc
HeapFree = windll.kernel32.HeapFree

buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 8 * sizeof(c_int))

ReadData(buffer)

result = (c_int * 8).from_address(buffer)

# result - массив целых, делаем, что надо и освобождаем память
HeapFree(GetProcessHeap(), 0, buffer)
а можно немного пояснений? я ничего не понял)

upd: наконец-то появилось время проверить код - работает!!! огромнейшее спасибо! но от пояснений я б все равно не отказался)
pyuser
razr
а можно немного пояснений? я ничего не понял)

upd: наконец-то появилось время проверить код - работает!!! огромнейшее спасибо! но от пояснений я б все равно не отказался)
может для начала документацию по ctypes почитать :) (http://python.net/crew/theller/ctypes/reference.html, если не знали)

GetProcessHeap = windll.kernel32.GetProcessHeap
HeapAlloc = windll.kernel32.HeapAlloc
HeapFree = windll.kernel32.HeapFree
это функции управления памятью (любой букварь по WinAPI)
buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 8 * sizeof(c_int))
выделяем память под результирующий буфер
ReadData(buffer)
без коментариев :)
result = (c_int * 8).from_address(buffer)
buffer это указатель на блок памяти, сообщаем Python'у, что это массив из восьми целых

код работы с массивом отсутствовал, потому и объяснение отсутствует

HeapFree(GetProcessHeap(), 0, buffer)
освобождаем память (правила хорошего тона)

можно попробовать так (давно с ctypes не работал):
buffer = c_int * 8 # объявляем массив
ReadData(buffer) # или ReadData(byref(buffer)) или ReadData(pointer(buffer)) не помню :(
for i in buffer.values :
print hex(i), # для каждого элемента массива выводим его шеснадцатиричное представление
если это работает, то и не стоит заморачиваться с функциями WinAPI
razr
pyuser
может для начала документацию по ctypes почитать :) (http://python.net/crew/theller/ctypes/reference.html, если не знали)
я читал ctypes tutorial и мало что оттуда понял. ctypes reference получше будет.

pyuser
GetProcessHeap = windll.kernel32.GetProcessHeap
HeapAlloc = windll.kernel32.HeapAlloc
HeapFree = windll.kernel32.HeapFree
это функции управления памятью (любой букварь по WinAPI)
buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 8 * sizeof(c_int))
выделяем память под результирующий буфер
вот это мне как раз было непонятно. правда вчера все-таки нагуглил что это за функции. как будет время полистаю какой-нибудь справочник по WinAPI.

pyuser
можно попробовать так (давно с ctypes не работал):
buffer = c_int * 8 # объявляем массив
ReadData(buffer) # или ReadData(byref(buffer)) или ReadData(pointer(buffer)) не помню :(
for i in buffer.values :
print hex(i), # для каждого элемента массива выводим его шеснадцатиричное представление
если это работает, то и не стоит заморачиваться с функциями WinAPI
вечером попробую. без WinAPI все выглядит намного проще)
pyuser
razr
вечером попробую. без WinAPI все выглядит намного проще)
:) трудно возразить
razr
pyuser
buffer = c_int * 8 # объявляем массив
ReadData(buffer) # или ReadData(byref(buffer)) или ReadData(pointer(buffer)) не помню :(
for i in buffer.values :
print hex(i), # для каждого элемента массива выводим его шеснадцатиричное представление
>>> lib.ReadData(buffer)                                                       
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't know how
to convert parameter 1
>>> lib.ReadData(byref(buffer))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: byref() argument must be a ctypes instance, not '_ctypes.ArrayType'
>>> lib.ReadData(pointer(buffer))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: _type_ must have storage info
не работает(( ну значит буду юзать код с WinAPI
pyuser
razr
pyuser
buffer = c_int * 8 # объявляем массив
ReadData(buffer) # или ReadData(byref(buffer)) или ReadData(pointer(buffer)) не помню :(
for i in buffer.values :
print hex(i), # для каждого элемента массива выводим его шеснадцатиричное представление
>>> lib.ReadData(buffer)                                                       
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't know how
to convert parameter 1
>>> lib.ReadData(byref(buffer))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: byref() argument must be a ctypes instance, not '_ctypes.ArrayType'
>>> lib.ReadData(pointer(buffer))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: _type_ must have storage info
не работает(( ну значит буду юзать код с WinAPI
я бы еще попробовал:
ReadData(addressof(buffer))
razr
pyuser
я бы еще попробовал:
Код:

ReadData(addressof(buffer))
не работает тож
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB