powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Помогите с подключением к DLL
17 сообщений из 17, страница 1 из 1
Помогите с подключением к DLL
    #39842711
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!

Пытаюсь подключиться к libpioneer3.dll, - DLL для работы с фискальным аппаратом Пионер 114ф.

В описании разработчик приводит пример инициализации сессии работы с ККТ по IP адресу на C++:

Код: plaintext
1.
int pioneer3_open (const char ∗host , uint16 timeout , const char∗ &response ) 



Параметры:
host IP-адрес ККТ
timeout таймаут ожидания ответа
response строка с результатом выполнения
Возвращает:
отрицательное число код ошибки
положительное число идентификатор сессии работы с ККТ, в дальнейшем
используется во всех командах.

Я попробовал перевести на Delphi:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
unit Un_Pioner;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    EditAddress: TEdit;
  
   
    procedure Button1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
 
  private
    { Private declarations }
    Procedure ShowDLLError(IDSession: Integer);
  public
    { Public declarations }
  end;

type
  Tpioneer3_version           = procedure(var Amajor: Integer; var Aminor: Integer; var Amicro: Integer; var Abuild: Integer); stdcall;
  Tpioneer3_open              = function(AIp_Addr: PChar;     ATimeOut: Integer; var AResponce: PChar):Integer; stdcall;
 ..................................................

var
  Form1: TForm1;
  dll_handle:        THandle;
  IDSession : integer;

  pioneer3_version           : Tpioneer3_version          ;
  pioneer3_open              : Tpioneer3_open             ;
 
......................................

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var Responce: PChar; IPAddress: PChar;
begin            
  IPAddress:=PChar(EditAddress.Text);  //  '192.168.0.150'
  if Assigned(pioneer3_open)
       then begin
              IDSession:=pioneer3_open(IPAddress, 5000, Responce);
               // Здесь возвращает IDSession = -2
              if IDSession<0 then ShowDLLError(IDSession);
              ShowMessage(Responce);
            end;
end;

procedure TForm1.FormShow(Sender: TObject);
  var Amajor, Aminor, Amicro, Abuild : Integer;
begin
  dll_handle := LoadLibrary('libpioneer3.dll');

  if (dll_handle <= 0) then ShowMessage('LoadLibrary: libpioneer3.dll not found.')
    else
      begin
         @pioneer3_version           := GetProcAddress(dll_handle, 'pioneer3_version');
         @pioneer3_open              := GetProcAddress(dll_handle, 'pioneer3_open');
..................................................................

         if Assigned(pioneer3_version)
              then begin
                     pioneer3_version(Amajor, Aminor, Amicro, Abuild);
                     Label1.Caption:='Версия библиотеки Пионер: ' + IntToStr(Amajor)+'.'+IntToStr(Aminor)+'.'+IntToStr(Amicro)+'.'+IntToStr(Abuild);
                   end;
       end;
end;

procedure TForm1.ShowDLLError(IDSession: Integer);
var Mess: String;
begin
  case IDSession of
   -1: Mess:='Неправильный handle';
   -2: Mess:='Ошибка подключения к ККТ';
   -3: Mess:='Ошибка передачи данных в ККТ';
   -4: Mess:='Таймаут получения ответа из ККТ';
   -5: Mess:='Ошибка в размере пакета данных';
   -6: Mess:='Неправильная контрольная сумма пакета данных';
   -7: Mess:='Неправильный заголовок пакета данных';
   -8: Mess:='Ошибка в параметрах команды (при разборе JSON)';
    else Mess:='Не определённая производителем ККМ ошибка';
   end;
  showmessage(Mess+'/код возврата из функции библиотеки:'+IntToStr(IDSession));
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeLibrary(dll_handle);
end;


end.



При запуске программы подключение к DLL проходит, о чём свидетельствует получение версии DLL,
однако попытка инициализации работы с ККТ по IP адресу дает "Ошибка подключения к ККТ" (-2).
Пинг аппарата по IP проходит.
Похоже, я напортачил с передачей параметров в функцию pioneer3_open, но разобраться где - не хватает опыта.

Помогите ПОЖ.!
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39842715
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во-первых, в описании на С++ ничего не сказано о stdcall, следовательно это cdecl.
Во-вторых, параметр timeout - 16-ти разрядный, а твой Integer явно шире.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39842727
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovВо-первых, в описании на С++ ничего не сказано о stdcall, следовательно это cdecl.
Во-вторых, параметр timeout - 16-ти разрядный, а твой Integer явно шире.



Да, в документации нашел:

Все команды имеют спецификацию вызова вида:
extern ”C” __declspec ( dllimport ) _cdecl
В дальнейшей документации при описании формата команд эта спецификация
опущена.


Переписал
Код: pascal
1.
2.
3.
type
  Tpioneer3_version  = procedure(var Amajor: Integer; var Aminor: Integer; var Amicro: Integer; var Abuild: Integer); cdecl;
  Tpioneer3_open     = function(const AIp_Addr: PChar; ATimeOut: UInt16;  var AResponce: PChar):Integer; cdecl;



Результат, увы, тот-же. Первая процедура выполняется, функция - нет.
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39842729
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
3 параметр строка. А память под нее кто выделять должен?
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39842733
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
const char * = в делфи PAnsiChar
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39842734
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
Tpioneer3_open     = function(const AIp_Addr: PAnsiChar; ATimeOut: UInt16;  var AResponce: PAnsiChar):Integer; cdecl;
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39842736
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11Tpioneer3_open = function( const AIp_Addr: PChar;

Вот этот const ты совершенно зря сюда впихнул. И да, если у тебя Delphi юникодная, то оно
должно быть AnsiChar всюду.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39842802
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так заработало:

Код: pascal
1.
  Tpioneer3_open  = function(const AIp_Addr: PAnsiChar; ATimeOut: UInt16;  var AResponce: PAnsiChar):Integer; cdecl;

,

так тоже работает:
Код: pascal
1.
  Tpioneer3_open  = function(AIp_Addr: PAnsiChar; ATimeOut: UInt16;  var AResponce: PAnsiChar):Integer; cdecl;



Вызов функции:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
procedure TForm1.Button1Click(Sender: TObject);
var Responce: PAnsiChar; IPAddress: PAnsiChar;
begin
  IPAddress:='192.168.0.150';
  if Assigned(pioneer3_open)
       then begin
              IDSession:=pioneer3_open(IPAddress, 5000, Responce);
              if IDSession<0 then ShowDLLError(IDSession);
              showMessage(Responce);
            end;
end;



Под память под строку с ответом, как пишут разработчики, выделяет и освобождает библиотека.

Спасибо всем, помогли.
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39842819
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
аж интересно стало - как длл узнает, что память под строку уже можно освобождать?
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39842837
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11,
Учти с таким подходом у тебя будут утечки памяти.
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39842838
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rаж интересно стало - как длл узнает, что память под строку уже можно освобождать?
Например, предполагается общий диспетчер памяти, а освобожденнием занимается клиент библиотеки.
Либо спецметод библиотеки, а освобождение вызовом этого метода также на клиенте.
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39842839
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ёёёёёVizit0rаж интересно стало - как длл узнает, что память под строку уже можно освобождать?
Например, предполагается общий диспетчер памяти, а освобожденнием занимается клиент библиотеки.
Либо спецметод библиотеки, а освобождение вызовом этого метода также на клиенте.
Скорее, второе:авторПод память под строку с ответом, как пишут разработчики, выделяет и освобождает библиотека.
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39842841
Фотография Gator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rаж интересно стало - как длл узнает, что память под строку уже можно освобождать?Попросить её (вызвать её процедуру, освобождающую память)?
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39842854
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rинтересно стало - как длл узнает, что память под строку уже можно освобождать?может и никак а тупо при очередном вызове освобождается
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39843243
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот в преамбуле к документации к библиотеке:

...........................
Все команды получают параметы и
возвращают ответ в виде null-терминированных строк. Память под строку с ответом выделяет и освобождает библиотека, поэтому нельзя освобождать указатель
на строку с ответом, а наоборот, для дальнейшего разбора рекомендуется скопировать строку ответа, выделив память в пользовательской программе.
Параметры и результаты выполнения оформлены в виде формате JSON, все
строковые данные должны быть в UTF-8.
............................
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39843274
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11, Тогда при объявлении переменных надо указывать ansistring(CP_UTF8).
...
Рейтинг: 0 / 0
Помогите с подключением к DLL
    #39843276
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11, вполне согласуется с моим предположением. в либе случаем не предполагается несколько вызовов параллельно?
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Помогите с подключением к DLL
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]