|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Работа со считывателем БСК MF-RW-USB
Всем доброго времени суток.
Суть вот в чем: 1. Есть считыватель БСК MF-RW-USB, который создает виртуальный COM порт средствами FT232. 2. Для общения со считывателес используется DLL библиотека, которая содержит в себе все необходимое. 3. Обмен данными со считывателем осуществляется с использованием проверки контрольных сумм по FCS алгаритму. Функция W_IO: обмен данными со считывателем Код:
function W_IO(Address, Cmd: char; BodyLen: integer; const CmdBody; var ReplyLen: integer; var Reply-Buffer): char; char W_IO(char Address, char Cmd, int BodyLen, void *CmdBody, int *ReplyLen, void *ReplyBuffer); Address адрес считывателя (0..3F) Cmd команда BodyLen длина дополнительных данных для команды CmdBody буфер, содержащий дополнительные данные ReplyLen длина данных, полученных от считывателя ReplyBuffer буфер, в который будут помещены полученные данные. При вызове функции в ReplyLen должен быть записан размер области памяти, отведенной под Reply- Buffer. На выходе в ReplyLen будет записана длина фактически полученных данных. Возвращаемое значение – код возврата, см. раздел «Константы» REPLY_XXXXX. Пример из мануала к библиотеке: Код:
procedure ReadEventLog; var Ret: char; RL: integer; Event: TEvent; begin // до вызова этой функции должна быть вызвана функция W_SetPortParams // читаем считыватель с адресом 3F repeat Ret := W_IO(#$3F, #$10, 0, '', RL, Event); if Ret = REPLY_OK then begin // Успешно прочитали событие, обрабатываем его… Ret := W_IO(#$3F, #$11, 0, '', RL, Event); if Ret <> REPLY_ACK then begin // Ошибка удаления последнего события – обрабатываем… end; end else begin // Ошибка чтения события – обрабатываем… end; until Ret <> REPLY_ACK; // выход из цикла чтения при ошибке end; Скажите пожалуйста, как сформировать запрос таким образом, чтобы ответ полученный от считывателя вписывался в Edit. В Edit необходимо вывести данные из ReplyBuffer. Еще было бы не плохо выкинуть настройки порта в ini Код:
t.Port:= 1; t.BaudRate:= 9600; t.WaitPortTimeout:= 200; t.ReadTotalTimeout:= 100; t.ReadNextByteTimeout:= 50; t.RecordSize:= 21; Прошу, не пинайте, в работе с портами я ноль, а сделать необходимо. Всем заранее огромное спасибо за помощь. |
#2
|
||||
|
||||
Цитата:
Код:
char W_IO(char Address, char Cmd, int BodyLen, void *CmdBody, int *ReplyLen, void *ReplyBuffer); настройки порта в ini - это работа с ini, перед открытием порта читаем из ini, перед закрытием программы пишем в ini Понять, что хочет заказчик - бесценно, ведь он платит MasterCard |
#3
|
|||
|
|||
Тоесть получается, что
Код:
function W_IO(Address, Cmd: char; BodyLen: integer; const CmdBody; var ReplyLen: integer; var Reply-Buffer): char; Код:
char W_IO(char Address, char Cmd, int BodyLen, void *CmdBody, int *ReplyLen, void *ReplyBuffer); на данный момент код выглядет так: Код:
unit Main_form; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, SyncObjs, ExtCtrls; type TMain = class(TForm) Button1: TButton; Button2: TButton; Edit1: TEdit; Edit2: TEdit; Label1: TLabel; Label2: TLabel; function LinkProc(ProcName: string):Pointer; procedure Read; procedure PortSetup; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; type PComInfo = ^ TComInfo; TComInfo = record RecordSize: DWORD; // Размер структуры, байт Port: BYTE; // Номер порта. 1 - COM1 и т.д. BaudRate: DWORD; // Скорость обмена WaitPortTimeout: DWORD; // Время ожидания доступности порта, мс ReadTotalTimeout: DWORD; // Время ожидания ответа считывателя, мс ReadNextByteTimeout: DWORD; // Время ожидания поступления очередного // байта при условии, что обнаружено начало // валидного кадра, мс. end; type PProtocolInfo = ^ TProtocolInfo; TProtocolInfo = record DisableAddress: BOOLEAN; // Размер структуры, байт CheckMode: INTEGER; // Режим проверки контрольной суммы end; // Описываем константы... const // Коды ответа оборудования REPLY_OK = #$00; //Команда выполнена успешно, получены данные REPLY_ACK_NACK = #$2A; //Признак кадра ACK/NACK, вне библиотеки не используется REPLY_ACK = #$55; //Получен ответ ACK REPLY_NACK1 = #$01; //Получен ответ NACK1 REPLY_NACK2 = #$02; //Получен ответ NACK2 REPLY_NACK3 = #$03; //Получен ответ NACK3 REPLY_NACK4 = #$04; //Получен ответ NACK4 REPLY_NACK5 = #$05; //Получен ответ NACK5 REPLY_NACK6 = #$06; //Получен ответ NACK6 // Коды ошибок при работе с портом REPLY_MISS = #$FF; //Ответ не получен (отсутствует считыватель) REPLY_ERR_OPENPORT = #$FE; //Ошибка открытия порта REPLY_ERR_WRITEPORT = #$FD; //Ошибка записи в порт REPLY_ERR_READPORT = #$FC; //Ошибка чтения из порта REPLY_ERR_LOCKPORT = #$FB; //Истек таймаут при попытке захватить порт REPLY_ERR_PORTNOTSET = #$FA; //Параметры порта не установлены REPLY_ERR_INVALIDANSWER = #$F9; //Ответ не удалось правильно интерпретировать REPLY_ERR_CRC = #$F8; //Ошибка контрольной суммы REPLY_ERR_INVALIDFRAME = #$F7; //Неверный идентификатор кадра // Методы расчета контрольной суммы кадра CHECK_NONE = #$00; //Не проверять контрольную сумму кадра CHECK_SUM = #$01; //Использовать суммирование (1 байт) CHECK_CRC16 = #$02; //Использовать CRC16 (2 байта) CHECK_FCS = #$03; //Использовать FCS (2 байта) var Ret: char; ReplyLen: integer; ReplyBuffer: char; Main: TMain; t: TComInfo; p: TProtocolInfo; W_SetPortParams: procedure(PortCfgPtr: PComInfo); stdcall; W_SetProtocolParams: procedure(ProtocolInfoPtr: PProtocolInfo); stdcall; W_IO: function (Address, Cmd: char; BodyLen: integer; const CmdBody; var ReplyLen: integer; var ReplyBuffer): char; stdcall; LibHandle: THandle; implementation uses StrUtils; {$R *.dfm} { TForm1 } function TMain.LinkProc(ProcName: string): Pointer; begin result:= GetProcAddress(LibHandle,PChar(ProcName)); end; // Устанавливаем параметры порта... procedure TMain.PortSetup; begin t.Port:=3; // Номер порта. 1 - COM1 и т.д. t.BaudRate:=115200; // Скорость обмена t.WaitPortTimeout:= 200; // Время ожидания доступности порта, мс t.ReadTotalTimeout:= 100; // Время ожидания ответа считывателя, мс t.ReadNextByteTimeout:= 50;// Время ожидания поступления очередного // байта при условии, что обнаружено начало // валидного кадра, мс. t.RecordSize:= 21; // Размер структуры, байт end; // Подключаем библиотеку... procedure TMain.FormCreate(Sender: TObject); begin LibHandle:= LoadLibrary('dll/ProX232.dll'); W_SetPortParams:= LinkProc('W_SetPortParams'); W_SetProtocolParams:= LinkProc('W_SetProtocolParams'); W_IO:= LinkProc('W_IO'); end; //Формируем запрос... procedure TMain.Read; begin Ret := W_IO(#$1, #$00, 0, '', ReplyLen, ReplyBuffer); if Ret = REPLY_OK then begin Edit1.Text:='Команда выполнена успешно, получены данные'; Edit2.Text:=(ReplyBuffer); end; if Ret= REPLY_ACK then begin Edit1.Text:='Получен ответ ACK'; Edit2.Text:=(ReplyBuffer); end; if Ret= REPLY_NACK6 then begin Edit1.Text:='Получен ответ NACK6'; Edit2.Text:=(ReplyBuffer); end; end; // Создаем подключение, Устанавливаем параметры протакола и отправляем запрос... procedure TMain.Button1Click(Sender: TObject); begin PortSetup; W_SetPortParams(@t); W_SetProtocolParams(@t); read; end; // Закрываем программу... procedure TMain.Button2Click(Sender: TObject); begin close; end; end. При таком раскладе программа корректно отправляет запрос, в сниффере видно, что ответ от ридера есть. В Edit1 все вписывается, так, как должно ( «Константы» REPLY_XXXXX определяются верно и ответ выводится верно), вот только в Edit2 вписывается 1. А вот с ответом в Edit1 у меня проюлемы. Я так понимаю, что необходимо использовать Код:
char W_IO(char Address, char Cmd, int BodyLen, void *CmdBody, int *ReplyLen, void *ReplyBuffer); Общение со считывателем осуществляется в щеснадцатиричной кодировке. С ini я вроде разобрался, спасибо. |
#4
|
||||
|
||||
у вас все вделано верно, почти
Цитата:
Код:
var ... ReplyBuffer: Pointer; ... begin // выделяем память ReplyLen:=255; ReplyBuffer:=GetMem(ReplyLen); Ret := W_IO(#$1, #$00, 0, '', ReplyLen, ReplyBuffer); // теперь по адресу ReplyBuffer находится массив полученного ответа //далее по тексту .. //вывод в Edit2 для начала можно так (см. коментарий в конце ответа) Edit2.Text:=PChar(ReplyBuffer); FreeMem(ReplyBuffer,ReplyLen); end; т.к. Цитата:
Понять, что хочет заказчик - бесценно, ведь он платит MasterCard Последний раз редактировалось cotseec, 14.10.2012 в 21:33. |
#5
|
|||
|
|||
Если запрос сформировать так:
Код:
procedure TMain.Read; begin ReplyLen:=255; ReplyBuffer:=GetMem(ReplyLen); Ret := W_IO(#$1, #$00, 0, '', ReplyLen, ReplyBuffer); if Ret = REPLY_OK then begin Edit1.Text:='Команда выполнена успешно, получены данные'; Edit2.Text:=PChar(ReplyBuffer); end; FreeMem(ReplyBuffer); end; Код:
ReplyBuffer:=GetMem(ReplyLen); Если сделать таким образом: Код:
procedure TMain.Read; begin ReplyLen:=255; ReplyBuffer:=GetMemory(ReplyLen); Ret := W_IO(#$1, #$00, 0, '', ReplyLen, ReplyBuffer); if Ret = REPLY_OK then begin Edit1.Text:='Команда выполнена успешно, получены данные'; Edit2.Text:=PChar(ReplyBuffer); end; FreeMemory(ReplyBuffer); end; Что я опять сделал не так? Привел запрос к следующму виду Код:
procedure TMain.Read; begin ReplyLen:=255; ReplyBuffer:=GetMemory(ReplyLen); Ret := W_IO(#$1, #$00, 0, '', ReplyLen, ReplyBuffer); if Ret = REPLY_OK then begin Edit1.Text:='Команда выполнена успешно, получены данные'; Edit2.Text:=PChar(GetMemory(ReplyLen)); end; //FreeMemory(ReplyBuffer); end; Если езменить ReplyLen:=25;, то вписывает - "TK•", но это не то, что мне необходимо вывести. В Edit2 должно выводиться примерно следующее - "31 33 20 4D 48 7A 20 52 65 61 64 65 72" При включении FreeMemory(ReplyBuffer);, программа при первом же запросе падает в ошибку, а при отключении при втором. Насколько можно судить по снифферу, так это происходит по потому что порт не закрывается, но если прописать неизвествую команду, то проблем нет, ровно как и ничего не вписывается в Edit. При выполнении запроса в цикле ошибка не выскакивает, программа ререстает отвечать, хотя со считывателем общается. Код:
procedure TMain.Read; begin repeat ReplyLen:=25; ReplyBuffer:=GetMemory(ReplyLen); Ret := W_IO(#$1, #$00, 0, '', ReplyLen, ReplyBuffer); if Ret = REPLY_OK then Edit1.Text:='Команда выполнена успешно, получены данные'; Edit2.Text:=PChar(GetMemory(ReplyLen)); until Ret = REPLY_ACK; // выход из цикла чтения при ошибке end; Последний раз редактировалось firmwares, 15.10.2012 в 07:16. |
#6
|
||||
|
||||
начнем сначала
прототип функции (в С) Цитата:
Цитата:
Код:
function W_IO(Adress:byte;Cmd:byte;BodyLen:integer; CmdBody:Pointer;ReplyLen:Pinteger;ReplyBuffer:Pointer):byte;stdcall адрес устройства, команда для устройства, размер буфера аргументов команды для устройства, указатель на буфер с аргументами команды для устройства, указатель на длину буфера для приема, указатель на сам буфер для приема работа с функцией: Код:
... var ... ReplyLen:integer; ReplyBuffer:Pointer; ... begin //определяем размер буфера и выделяем под него память ReplyLen:=$FF; ReplyBuffer:=GetMemory(ReplyLen); //если нужен цикл, то начало цикла тут // начало цикла ... Ret := W_IO(#$1, #$00, 0, '', @ReplyLen, ReplyBuffer); if Ret = REPLY_OK then begin Edit1.Text:='Команда выполнена успешно, получены данные'; Edit2.Text:=PChar(ReplyBuffer);// PChar(GetMemory(ReplyLen));как у вас - бред, пытаемся просто отбразить только что выделеную память end; ... // тут конец цикла ... FreeMemory(ReplyBuffer);// в конце освобождаем память end; для того, чтобы этот результат был в виде Цитата:
З.Ы. как вариант функция сама определяет ReplyBuffer и ReplyLen и все выделения памяти в программе не нужны, тогда как dll освобождает память после ее использования? З.Ы.Ы. или закручено еще круче: функция после своей работы выбрасывает по адресу ReplyLen длину необходимого ей буфера, а при следующем своем вызове заполняет его (или какой-то другой функцией), но это из области фантазий - нужно смотреть докуметацию или коментарии к библиотеке, если таковые есть З.Ы.Ы.Ы а может проще написать свой класс работы с СОМ портом, тем более протокол известен, кто знает какие там ошибки в dll а так, если не работает - сам дурак Понять, что хочет заказчик - бесценно, ведь он платит MasterCard Последний раз редактировалось cotseec, 15.10.2012 в 10:42. |
#7
|
|||
|
|||
Уважаемый cotseec,
Скажите пожалуйста, в чем может быть проблема? Читая в очередной раз жоки на протакол и библиотеку, я наткнулся на следующее Методы расчета контрольной суммы кадра CHECK_NONE - 0х00 //Не проверять контрольную сумму кадра CHECK_SUM - 0х01 //Использовать суммирование (1 байт) CHECK_CRC16 - 0х02 //Использовать CRC16 (2 байта) CHECK_FCS - 0х03 //Использовать FCS (2 байта) И тут я нашел свою первую ошибку, в следствии чего программа падает в ошибку. Найти нашел, но как исправить не пойму. изначально W_SetProtocolParams(@t); у меня ссылался на TComInfo;, а должен на TProtocolInfo; со следующей структурой. Структура TProtocolInfo: DisableAddress - BOOLEAN //Размер структуры, байт CheckMode - INTEGER //Режим проверки контрольной суммы Добавилв код следующее: Код:
procedure TForm1.Button2Click(Sender: TObject); var Prot: TProtocolInfo; begin // Prot.DisableAddress:='Это в коментах потому что не могу сообразить, как правильно заполнить'; // Размер структуры, байт Prot.CheckMode:=03; // Режим проверки контрольной суммы W_SetProtocolParams(@Prot) end; Сейчас переписал все заново и разбил все по кускам (вывел в отдельные кнопки каждую часть - подключение. установку протакола и сам запрос) Теперь код такой: Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, SyncObjs; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Edit1: TEdit; Edit2: TEdit; function LinkProc(ProcName: string):Pointer; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private { Private declarations } public { Public declarations } end; type PComInfo = ^ TComInfo; TComInfo = record RecordSize: DWORD; // Размер структуры, байт Port: BYTE; // Номер порта. 1 - COM1 и т.д. BaudRate: DWORD; // Скорость обмена WaitPortTimeout: DWORD; // Время ожидания доступности порта, мс ReadTotalTimeout: DWORD; // Время ожидания ответа считывателя, мс ReadNextByteTimeout: DWORD; // Время ожидания поступления очередного // байта при условии, что обнаружено начало // валидного кадра, мс. end; type PProtocolInfo = ^ TProtocolInfo; TProtocolInfo = record DisableAddress: BOOLEAN; // Размер структуры, байт CheckMode: INTEGER; // Режим проверки контрольной суммы end; var Form1: TForm1; // набор импортируемых функций W_SetPortParams: procedure(PortCfgPtr: PComInfo); stdcall; W_SetProtocolParams: procedure(ProtocolInfoPtr: PProtocolInfo); stdcall; W_IO: function(Address, Cmd: char; BodyLen: integer; const CmdBody; var ReplyLen: integer; var ReplyBuffer): char; stdcall; LibHandle: THandle; implementation {$R *.dfm} { TForm1 } { TForm1 } function TForm1.LinkProc(ProcName: string): Pointer; begin try result:= GetProcAddress(LibHandle,PChar(ProcName)); Win32Check(Assigned(Result)) except end end; // Подключаем DLL.... procedure TForm1.FormCreate(Sender: TObject); begin LibHandle:= LoadLibrary('dll/ProX232.dll'); Win32Check(LibHandle<>0); W_SetPortParams:= LinkProc('W_SetPortParams'); W_IO:= LinkProc('W_IO'); end; // Устанавливаем параметры порта и создаем подключение.... procedure TForm1.Button1Click(Sender: TObject); var t: TComInfo; begin t.Port:= 3; t.BaudRate:= 115200; t.WaitPortTimeout:= 200; t.ReadTotalTimeout:= 100; t.ReadNextByteTimeout:= 50; t.RecordSize:= 21; // dword = 4 байтам W_SetPortParams(@t) end; // Устанавливаем параметры протакола.... procedure TForm1.Button2Click(Sender: TObject); var Prot: TProtocolInfo; begin //Prot.DisableAddress:=00; // Размер структуры, байт Prot.CheckMode:=03; // Режим проверки контрольной суммы W_SetProtocolParams(@Prot) end; // Формирем и отправляем запрос.... procedure TForm1.Button3Click(Sender: TObject); // Описываем константы.... Const REPLY_OK = #$0; REPLY_ACK = #$55; var // Выводим переменные.... Ret:char; ReplyLen:integer; ReplyBuffer:Pointer; begin //определяем размер буфера и выделяем под него память.... ReplyLen:=$FF; ReplyBuffer:=GetMemory(ReplyLen); // Формируем и отправляем запрос.... Ret := W_IO(#$1, #$00, 0, '', ReplyLen, ReplyBuffer); if Ret = REPLY_OK then begin // Выводим ответ от считывателя... Edit1.Text:='Команда выполнена успешно, получены данные'; Edit2.Text:=PChar(ReplyBuffer);// PChar(GetMemory(ReplyLen)); end; // Освобождаем память... FreeMemory(ReplyBuffer); end; end. Не пойму несколько вещей. 1. Как правильно настроить параметры установки протакола 2. Почему при нажатии Button2 программа падает в ошибку"access violation at address" 3. Почему раньше параметры устанавливались, но как и сейчас прорамма падала в ошибку. Последний раз редактировалось firmwares, 16.10.2012 в 01:46. |
#8
|
|||
|
|||
Привел обработчик Button2 к следующему виду.
Код:
// Устанавливаем параметры протакола.... procedure TForm1.Button2Click(Sender: TObject); var Prot: TProtocolInfo; begin Prot.DisableAddress:=true; // Размер структуры, байт Prot.CheckMode:=03; // Режим проверки контрольной суммы W_SetProtocolParams(@Prot) end; Вопрос по поводу "access violation at address" все еще открыт. Не могу догнать почему это происходит. И еще! Если в запросе поставить Код:
Ret := W_IO(#$1, #$00, 0, '', @ReplyLen, ReplyBuffer); Код:
Ret := W_IO(#$1, #$00, 0, '', ReplyLen, ReplyBuffer); [Error] Unit1.pas(120): Types of actual and formal var parameters must be identical Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, SyncObjs; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Edit1: TEdit; Edit2: TEdit; function LinkProc(ProcName: string):Pointer; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private { Private declarations } public { Public declarations } end; type PComInfo = ^ TComInfo; TComInfo = record RecordSize: DWORD; // Размер структуры, байт Port: BYTE; // Номер порта. 1 - COM1 и т.д. BaudRate: DWORD; // Скорость обмена WaitPortTimeout: DWORD; // Время ожидания доступности порта, мс ReadTotalTimeout: DWORD; // Время ожидания ответа считывателя, мс ReadNextByteTimeout: DWORD; // Время ожидания поступления очередного // байта при условии, что обнаружено начало // валидного кадра, мс. end; type PProtocolInfo = ^ TProtocolInfo; TProtocolInfo = record DisableAddress: BOOLEAN; // Размер структуры, байт CheckMode: INTEGER; // Режим проверки контрольной суммы end; var Form1: TForm1; // набор импортируемых функций W_SetPortParams: procedure(PortCfgPtr: PComInfo); stdcall; W_SetProtocolParams: procedure(ProtocolInfoPtr: PProtocolInfo); stdcall; W_IO: function(Address, Cmd: char; BodyLen: integer; const CmdBody; var ReplyLen: integer; var ReplyBuffer): char; stdcall; LibHandle: THandle; implementation {$R *.dfm} { TForm1 } { TForm1 } function TForm1.LinkProc(ProcName: string): Pointer; begin result:= GetProcAddress(LibHandle,PChar(ProcName)); end; // Подключаем DLL.... procedure TForm1.FormCreate(Sender: TObject); begin LibHandle:= LoadLibrary('dll/ProX232.dll'); W_SetPortParams:= LinkProc('W_SetPortParams'); W_SetProtocolParams:= LinkProc('W_SetProtocolParams'); W_IO:= LinkProc('W_IO'); end; // Устанавливаем параметры порта и создаем подключение.... procedure TForm1.Button1Click(Sender: TObject); var t: TComInfo; begin t.Port:= 3; t.BaudRate:= 115200; t.WaitPortTimeout:= 200; t.ReadTotalTimeout:= 100; t.ReadNextByteTimeout:= 50; t.RecordSize:= 21; // dword = 4 байтам W_SetPortParams(@t) end; // Устанавливаем параметры протакола.... procedure TForm1.Button2Click(Sender: TObject); var Prot: TProtocolInfo; begin Prot.DisableAddress:=true; // Размер структуры, байт Prot.CheckMode:=03; // Режим проверки контрольной суммы W_SetProtocolParams(@Prot) end; // Формирем и отправляем запрос.... procedure TForm1.Button3Click(Sender: TObject); // Описываем константы.... Const REPLY_OK = #$0; REPLY_ACK = #$55; var // Выводим переменные.... Ret:Char; ReplyLen:integer; ReplyBuffer:Pointer; begin //определяем размер буфера и выделяем под него память.... ReplyLen:=255; ReplyBuffer:=GetMemory(ReplyLen); // Формируем и отправляем запрос.... Ret := W_IO(#$1, #$00, 0, '', @ReplyLen, ReplyBuffer); if Ret = REPLY_OK then begin // Выводим ответ от считывателя... Edit1.Text:='Команда выполнена успешно, получены данные'; Edit2.Text:=PChar(ReplyBuffer); end; // Освобождаем память... FreeMemory(ReplyBuffer); end; end. |
#9
|
||||
|
||||
Цитата:
судя по этому Цитата:
Цитата:
Код:
W_IO: function(Address, Cmd: char; BodyLen: integer; const CmdBody; var ReplyLen: integer; var ReplyBuffer): char; stdcall; по поводу констант Цитата:
З.Ы. задача по выводу ответа железки решена? Понять, что хочет заказчик - бесценно, ведь он платит MasterCard Последний раз редактировалось cotseec, 16.10.2012 в 20:07. |
#10
|
|||
|
|||
Цитата:
Уважаемый cotseec, вы говорили, что Цитата:
Не могли бы Вы рассказать об том поподробнее, может хоть с так получится. Дело вот в чем: Мне необходимо написать программу, которая будет висеть в трее или работать как служба. Программа просто опрашывает считыватель на предмет поиска карты и как только видит карту считывает ее код. Считав код, программа вписывает его там, где стоит курсор. С эмуляцией клавиатуры думаю проблем не возникнет, а вот со считыванием даллых с ридера...... это проблема. Я с этим считывателем долблюсь хрен знает сколько и ничего не получается. |
#11
|
||||
|
||||
проверьте личную почту на форуме
Понять, что хочет заказчик - бесценно, ведь он платит MasterCard |
Этот пользователь сказал Спасибо cotseec за это полезное сообщение: | ||
firmwares (19.10.2012)
|