Подключение dll на С++ к Lazarus

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
DmitriyX
незнакомец
Сообщения: 7
Зарегистрирован: 10.02.2017 13:02:42

Подключение dll на С++ к Lazarus

Сообщение DmitriyX »

Здравствуйте
Есть прибор TESTER ARINC http://www.elcus.ru/pribors.php?ID=test-arinc
для управления им через COM порт есть ПО, библиотека TesterArinc_DLL_W2K.dll для XP
Библиотек написана на с++ исходников нету
Пытаюсь подключить функцию:
Описание:
void version_TesterArinc_DLL (char *lpcod )-Функция возвращает номер версии библиотеки.
Параметры:
lpcod - указатель на массив char[4], в который возвращается версия библиотеки

В файле TesterArinc_DLL_W2K.h функция прописана как:

Код: Выделить всё

TestDLL void __stdcall version_TesterArinc_DLL(char * );


Приведен Пример вызова на С++ :

Код: Выделить всё

//2/29/Чтение версии библиотеки
   char ver[4];
   version_TesterArinc_DLL(ver );
    MessageBox   (NULL,ver,"DLL version",MB_OK);


Делаю в Lazarus:

Код: Выделить всё

unit Unit1;
{$mode objfpc}{$H+}
interface
uses
    Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
    { TForm1 }
    TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
    private
    public
    end;

var
    Form1: TForm1;
implementation
{$R *.lfm}

procedure version_TesterArinc_DLL(var s:PChar);stdcall; external 'TesterArinc_DLL_W2K.dll';

{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var k:PChar;
begin
    version_TesterArinc_DLL(k);
end;                                   


При запуске появляется сообщение: "Точка входа в процедуру version_TesterArinc_DLL в библиотеке не найдена
В чём может быть проблема?
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

После названия DLL не пробовали name дополнительно указывать?
Аватара пользователя
bormant
постоялец
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Сообщение bormant »

Следующей проблемой будет var s: PChar вместо s: PChar, в прототипе же char*, а не char**.
DmitriyX
незнакомец
Сообщения: 7
Зарегистрирован: 10.02.2017 13:02:42

Сообщение DmitriyX »

Сделал так:

Код: Выделить всё

procedure version_TesterArinc_DLL(vv:PChar);stdcall; //stdcall;
external 'TesterArinc_DLL_W2K.dll' index 29 ;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var kk:PChar;
  d:string;
begin
  d:='0';
  kk:=@d;
  version_TesterArinc_DLL(kk);
  memo1.lines.add(strpas(kk));
  kk:=nil;
end;                                     


Почему- то работает странно: если сделать быструю компиляцию, и запустить, то все нормально
1.JPG

если повторно запусть, либо повторно сделать быструю компиляцию, то в мемо успевает вывести результат, сразу вы
летает сообщение об ошибке
Снимок.JPG


Использовал name вместо index также все происходит, имя брал с помощью Dependency Walker
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
serbod
постоялец
Сообщения: 449
Зарегистрирован: 16.09.2016 10:03:02
Откуда: Минск
Контактная информация:

Сообщение serbod »

Ты передаешь в функцию адрес паскалевской string, который нифига не сишный char *
Надо так:
version_TesterArinc_DLL(PChar(d));


И еще, по описанию функция возвращает null-terminated string, а в какую память оно ее запишет? Ты ей один байт выделил. А в сишном примере было 4 байта. Делай тогда:
d := '0000';
DmitriyX
незнакомец
Сообщения: 7
Зарегистрирован: 10.02.2017 13:02:42

Сообщение DmitriyX »

Нашел в чем ошибка. добавил new() все заработало
procedure TForm1.Button1Click(Sender: TObject);
var kk:pchar;
begin
new(kk);
version_TesterArinc_DLL(kk);
memo1.lines.add(strpas(kk));
end;
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

DmitriyX писал(а):Нашел в чем ошибка. добавил new() все заработало


ага, прям нашел. :D
Ошибка-то как была, так и осталась, причем принципиальная: выделено 1 байт, в этот один байт пересылается четыре. А то что работает - так это временно.
DmitriyX
незнакомец
Сообщения: 7
Зарегистрирован: 10.02.2017 13:02:42

Сообщение DmitriyX »

Все работает, вылетов нет
Аватара пользователя
serbod
постоялец
Сообщения: 449
Зарегистрирован: 16.09.2016 10:03:02
Откуда: Минск
Контактная информация:

Сообщение serbod »

DmitriyX писал(а):Все работает, вылетов нет

Тебе просто повезло, что менеджер памяти выделяет не по одному байту, а по 4 как минимум. Но это решение в принципе неправильное, тем более, что возврата памяти обратно я не вижу, будет утечка.

Либо выделяй 4 байта через GetMem(kk, 4) и затем FreeMem(kk), либо через SetLength(string, 4), а память сама вернется.
Ответить