Форум сайта python.su
пишу программу для цифрового 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
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;
Офлайн
попробовал в SetGain использовать windll вместо cdll:
>>> from ctypes import *
>>> lib=windll.k8047d
>>> lib.StartDevice()
>>> lib.SetGain(1,1)
0
Офлайн
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)
Офлайн
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)
Отредактировано (Фев. 17, 2009 21:12:01)
Офлайн
razrможет для начала документацию по ctypes почитать :) (http://python.net/crew/theller/ctypes/reference.html, если не знали)
а можно немного пояснений? я ничего не понял)
upd: наконец-то появилось время проверить код - работает!!! огромнейшее спасибо! но от пояснений я б все равно не отказался)
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)
HeapFree(GetProcessHeap(), 0, buffer)
buffer = c_int * 8 # объявляем массив
ReadData(buffer) # или ReadData(byref(buffer)) или ReadData(pointer(buffer)) не помню :(
for i in buffer.values :
print hex(i), # для каждого элемента массива выводим его шеснадцатиричное представление
Офлайн
pyuserя читал ctypes tutorial и мало что оттуда понял. ctypes reference получше будет.
может для начала документацию по ctypes почитать :) (http://python.net/crew/theller/ctypes/reference.html, если не знали)
pyuserвот это мне как раз было непонятно. правда вчера все-таки нагуглил что это за функции. как будет время полистаю какой-нибудь справочник по WinAPI.это функции управления памятью (любой букварь по WinAPI)GetProcessHeap = windll.kernel32.GetProcessHeap
HeapAlloc = windll.kernel32.HeapAlloc
HeapFree = windll.kernel32.HeapFreeвыделяем память под результирующий буферbuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 8 * sizeof(c_int))
pyuserвечером попробую. без WinAPI все выглядит намного проще)
можно попробовать так (давно с ctypes не работал):если это работает, то и не стоит заморачиваться с функциями WinAPIbuffer = c_int * 8 # объявляем массив
ReadData(buffer) # или ReadData(byref(buffer)) или ReadData(pointer(buffer)) не помню :(
for i in buffer.values :
print hex(i), # для каждого элемента массива выводим его шеснадцатиричное представление
Офлайн
razr:) трудно возразить
вечером попробую. без WinAPI все выглядит намного проще)
Офлайн
pyuserbuffer = 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
Отредактировано (Фев. 18, 2009 21:24:54)
Офлайн
razrя бы еще попробовал:pyuserbuffer = c_int * 8 # объявляем массив
ReadData(buffer) # или ReadData(byref(buffer)) или ReadData(pointer(buffer)) не помню :(
for i in buffer.values :
print hex(i), # для каждого элемента массива выводим его шеснадцатиричное представлениене работает(( ну значит буду юзать код с WinAPI>>> 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
ReadData(addressof(buffer))
Офлайн
pyuserне работает тож
я бы еще попробовал:
Код:
ReadData(addressof(buffer))
Офлайн