DLL, string и sharemem

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

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

DLL, string и sharemem

Сообщение tria » 09.02.2018 19:45:08

В процессе написания ДЛЛ.
Нужно передавать string и record.
В вызывающей программе и в ДЛЛ первым модулем в uses прописал sharemem.
Откомпилировал fpcmemdll и fpcmemdll.dll положил возле вызывающей программы.
Все одно при попытке вызова функции с параметром типа string вылет.

Что делаю не так?
Должна ли такая схема в будущем работать в Линукс?
Если отказаться от sharemem, то как лучше передавать string?
Лазарь 1.6.4

Код:
Проба обратного вызова процедуры из формы вызывающей программы.
Вызывающая программа:
Код: Выделить всё
//Эта процедура будет вызваться из ДЛЛ
procedure Imp_MyShowMes(fm:TForm1; txt:string);
begin
  fm.MyShowMes(txt);
end;

procedure TForm1.MyShowMes(txt:string);
begin
  ShowMessage(txt);
end;

//Процедура загружает ДЛЛ, передает в нее ссылку на форму
//и вызывает процедуру, которая вызывает Imp_MyShowMes
procedure TForm1.Button2Click(Sender: TObject);
type
  TDLLShowMes=procedure(fm:Tform); stdcall;
var
  DLLhnd: THandle = 0;
  DLLShowMes:TDLLShowMes;
begin
  DLLhnd:=LoadLibrary('CallBackDLL.dll');
  If DLLhnd=0 Then begin
    ShowMessage('CallBackDLL.dll не найдена');
    Exit;
  end;
  DLLShowMes:=TDLLShowMes(GetProcAddress(DLLhnd, 'DLLShowMes'));
  If DLLShowMes=nil Then begin
    ShowMessage('DLLShowMes не найдена');
    Exit;
  end;
  DLLShowMes(self);
end;

exports Imp_MyShowMes index 1 name 'Imp_MyShowMes';


Код в ДЛЛ:
Код: Выделить всё
library CallBackDLL;

{$mode objfpc}{$H+}

uses
  sharemem,
  Classes, Windows
  { you can add units after this };

type
  TProcImp_MyShowMes=procedure(fm:pointer; txt:string);stdcall; //: Imp_MyShowMes(fm:TForm1);stdcall;

var fm:Pointer;

procedure DLLShowMes(fm:Pointer);
var EXEProc:TProcImp_MyShowMes;
begin
  EXEProc:=TProcImp_MyShowMes(GetProcAddress(GetModuleHandle(nil), 'Imp_MyShowMes'));
  EXEProc(fm, 'Привет из ДЛЛЛ');
end;

exports DLLShowMes;
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: DLL, string и sharemem

Сообщение LearnMagic » 09.02.2018 20:11:28

var fm:Pointer;

procedure DLLShowMes(fm:Pointer);
var EXEProc:TProcImp_MyShowMes;
begin
EXEProc:=TProcImp_MyShowMes(GetProcAddress(GetModuleHandle(nil), 'Imp_MyShowMes'));
EXEProc(fm, 'Привет из ДЛЛЛ'); какая из fm используется и инициализирована ли она
end;
LearnMagic
новенький
 
Сообщения: 66
Зарегистрирован: 10.11.2016 23:13:38

Re: DLL, string и sharemem

Сообщение serbod » 10.02.2018 06:53:04

Рекомендую в экпортируемых функциях DLL использовать только типы фиксированного размера памяти. То есть ShortString и packed record без динамических массивов и строк.

А также рекомендую проектировать DLL как библиотеку функций, а не как приложение.
Аватара пользователя
serbod
постоялец
 
Сообщения: 449
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: DLL, string и sharemem

Сообщение Снег Север » 10.02.2018 07:49:19

serbod писал(а):Рекомендую в экпортируемых функциях DLL использовать только типы фиксированного размера памяти. То есть ShortString и packed record без динамических массивов и строк.
А также рекомендую проектировать DLL как библиотеку функций, а не как приложение.
Так, конечно, надежнее всего. Но по опыту вполне можно и динамические структуры передавать. Самое важное - правильно указывать порядок аргументов - ключевые слова cdecl или stdcall в описании функций/процедур.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2990
Зарегистрирован: 27.11.2007 16:14:47

Re: DLL, string и sharemem

Сообщение tria » 10.02.2018 10:28:40

LearnMagic писал(а):var fm:Pointer;

procedure DLLShowMes(fm:Pointer);
var EXEProc:TProcImp_MyShowMes;
begin
EXEProc:=TProcImp_MyShowMes(GetProcAddress(GetModuleHandle(nil), 'Imp_MyShowMes'));
EXEProc(fm, 'Привет из ДЛЛЛ'); какая из fm используется и инициализирована ли она
end;


fm - это форма из вызывающего приложения:
Код: Выделить всё
DLLShowMes(self);
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: DLL, string и sharemem

Сообщение Снег Север » 10.02.2018 11:04:39

tria, в лазаре использовать формы из dll крайне нежелательно. Это даже в делфи плохо работает, а там это на порядок лучше реализовано. На худой конец, можно использовать формы чисто локализованные в dll, но данные туда и обратно передавать только обычными переменными.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2990
Зарегистрирован: 27.11.2007 16:14:47

Re: DLL, string и sharemem

Сообщение tria » 10.02.2018 11:06:43

Снег Север писал(а):
serbod писал(а):Рекомендую в экпортируемых функциях DLL использовать только типы фиксированного размера памяти. То есть ShortString и packed record без динамических массивов и строк.
А также рекомендую проектировать DLL как библиотеку функций, а не как приложение.
Так, конечно, надежнее всего. Но по опыту вполне можно и динамические структуры передавать. Самое важное - правильно указывать порядок аргументов - ключевые слова cdecl или stdcall в описании функций/процедур.


Шел вчера домой, и сам об этом подумал. И таки да, в ехе забыл указать:
Код: Выделить всё
//Эта процедура будет вызваться из ДЛЛ
procedure Imp_MyShowMes(fm:TForm1; txt:string); [color=#FF0000]stdcall;[/color]


Но это была проба технологии, а в реалии мне нужно будет передвать и строки, и record содержащие variant.

Добавлено спустя 2 минуты 2 секунды:
Снег Север писал(а):tria, в лазаре использовать формы из dll крайне нежелательно. Это даже в делфи плохо работает, а там это на порядок лучше реализовано. На худой конец, можно использовать формы чисто локализованные в dll, но данные туда и обратно передавать только обычными переменными.


В ДЛЛ у меня не будет формы. Форма взята как пример объекта из вызывающей ДЛЛ программы.
Мне в ДЛЛ нужно будет вызывать методы объектов основной программы.
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: DLL, string и sharemem

Сообщение Снег Север » 10.02.2018 14:14:51

Для винды я реализовывал такое через messaage'ы. Просто и надежно. Передаем в dll handle главной формы и ловим в ней. Если же нужна кроссплатформенность, то просто не знаю, как там в *nix'ах.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2990
Зарегистрирован: 27.11.2007 16:14:47


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8

Рейтинг@Mail.ru