Странная ошибка при создании dll

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

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

Ответить
AlexNightingaller
новенький
Сообщения: 19
Зарегистрирован: 08.06.2011 10:41:16

Странная ошибка при создании dll

Сообщение AlexNightingaller »

Попробовал написать простую dll.
Вот код:

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

library project1;

{$mode objfpc}{$H+}

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

{$IFDEF WINDOWS}{$R project1.rc}{$ENDIF}

procedure SM; stdcall; export;
begin
ShowMessage('S');
end;

Exports SM;
begin
end.


Ругается на ShowMessage, но ведь юнит Dialogs прописан. Ничего не понимаю, в чем дело?
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

Подключаем пакет LCL. А лучше вообще забыть про данные функции и про GUI часть LCL.
Аватара пользователя
dunin
энтузиаст
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и
Контактная информация:

Сообщение dunin »

Крячился как-то с этой проблемой...
Не все что можно сделать в дельфи делается и в лазарусе и наоборот... Или из Dll нельзя форму создать или руки кривые. Лучше верни из библиотеки значение 'S' основному модулю как резалт функции и оттуда выведи сообщение.
AlexNightingaller
новенький
Сообщения: 19
Зарегистрирован: 08.06.2011 10:41:16

Сообщение AlexNightingaller »

Mr.Smart писал(а):Подключаем пакет LCL. А лучше вообще забыть про данные функции и про GUI часть LCL.

Немного не понял: как подключаем пакет LCL?
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

Способ получить кучу "мёртвого" кода или как не нужно программировать :wink:
http://freepascal.ru/forum/viewtopic.php?f=5&t=6210&p=45674#p45673
Maxizar
постоялец
Сообщения: 385
Зарегистрирован: 20.03.2010 18:48:14

Сообщение Maxizar »

Эх… опять все сказали что да как, но никто ничего не объяснил :(

Как скажет один из моих преподавателей: «Смотри Сюда!»
МатЧасть.:
Когда Вы программируете на Lazarus и пишете GUI , то Lazarus играет роль IDE во всех смыслах этого слова. (Но нужно понимать, что вы используете (ну не вы а IDE вообще-то) компилятор FPC).
Когда же Вы при помощи Lazarus, пишете DLL, то на самом деле он как бы перестал играть роль IDE, а стал ну как бы навороченным блокнотом, который скормит ваш исходник FPC и все. Вот в этом и все, кроится ваша проблема.
А именно, FPC не имеет никакого понятия о модуле Dialogs. Потому что это часть LCL(библиотека(набор модулей и классов) Lazarus-а), а компилятор знаете только о своем наборе модулей и классов а именно об FCL (библиотека(набор модулей и классов) языка Free Pascal).
По этому чтобы все работало, в проекте нужно дописать(прописать) дополнительные пути до той самой LCL, чтобы FPC как компилятор смог понять что блин вот откуда мне брать модуль Dialogs.
Долго писать что да как, привожу скриншот:
Изображение


Подключаем пакет LCL. А лучше вообще забыть про данные функции и про GUI часть LCL.


По идее это правильно, но иногда нужно скрыть реализацию именно GUI и ниже с ней логики в DLL и выдавать лишь интерфейсный модуль, мол пользуйтесь, но я вам не скажу как я это сделал.

В чем тут сложность и всякие не хорошие вещи. Нужно как я писал выше прописать пути до LCL, и делать нечто подобное:

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

library mylib;

{$mode objfpc}{$H+}

uses
  Classes,Forms, Interfaces, Unit1
  { you can add units after this };

{$R *.res}

procedure Show1; stdcall; export;
var NForm:TForm1;
begin
   Application.Initialize;
    NForm:=TForm1.Create(Application);
    try
      NForm.ShowModal;
    finally
      NForm.Free;
      end;
end;

Exports Show1 index 1;

begin
end.


Обратите внимание на строчку:

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

Application.Initialize;


После этого можно юзать форму спрятанную в DLL в вашем приложении.

Теперь, что касается именно вашей проблемы, онa решается аналогичным способом:

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

library mylib;

{$mode objfpc}{$H+}

uses
  Classes,Forms, Interfaces,  Dialogs
  { you can add units after this };

{$R *.res}

procedure Show1; stdcall; export;
begin
  Application.Initialize;
  ShowMessage('S');
  //MessageDlg('S','',mtError,[mbNo],'ad');  //можно и Тае еще :)
end;

Exports Show1 index 1;

begin
end.


Долго писать, если интересно смотрите прилагаемые исходники…

Что касается ГУИ в ДЛЛ вообще да лучше так не делать… да и не зачем… а вот что касается логики, процедур, функций то да… на то ДЛЛ и созданы.

Но и даже в этом случае, нужно помнить о том, что нужно возвращать простые типы и т.п., но это уже другая тема.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

Maxizar Стоит упомянуть о менеджере памяти, а то потом возникнет следующий вопрос:
Возникает ошибка AccessViolation. Не пойму откуда она - ведь всё правильно написано :shock:


Добавлено спустя 2 минуты 1 секунду:
Да и правильнее будет не добавлять пути как вы, а подключить непосредственно пакет LCL в Инспекторе проекта.
Ответить