Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.10.30;
Скачать: CL | DM;

Вниз

Не закрывается приложение при работе с DLL   Найти похожие ветки 

 
Norfolk ©   (2005-10-04 22:43) [0]

Уважаемые Мастера.
Имеется приложение, которое вызывает форму из DLL. Всё работает как надо, форма из библиотеки вызывается, но когда форма заканчивает работать программа не закрывается, возникает ошибка, что-то вроде Приложение обратилось к памяти по адресу ...(адрес).... Память не может быть "Read". Нажмите ОК для завершения приложения. Такая ошибка возникает только если форма в библиотеке хоть немного сложная и насыщеная элементами. Если же форма в DLL пустая или на ней всего пару кнопок - то всё нормально, всё закрывается и работает.


 
Германн ©   (2005-10-05 00:30) [1]

А стоило ли пихать форму в DLL?
Столько уже истрачено черных пикселей на слова о "кривости" данного подхода.


 
Delphi_is_cool ©   (2005-10-05 00:46) [2]

Подключен ли модуль ShareMem ?
Если нет, то его нужно подключить в Dll"ке и в самом проекте(Project->View Source)

ps
Лчуше вместо модуля ShareMem использовать модуль FastShareMem(его можно найти в интернете).


 
GanibalLector ©   (2005-10-05 02:38) [3]

2 Norfolk ©   (04.10.05 22:43)
Тысяча элементов тебя устроит???

DLL :

library Project1;
uses
 SysUtils,
 Classes,
 Unit1 in "Unit1.pas" {Form1};
Exports
 ShowMyForm;
{$R *.RES}
begin
end.

\\\\\\\\\\\\\\\
unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure FormCreate(Sender: TObject);
 private
 public
   procedure CClick(Sender: TObject);
 end;

 procedure ShowMyForm(Handle:HWND);stdcall;

var
 Form1: TForm1;

implementation

{$R *.DFM}

procedure ShowMyForm(Handle:HWND);stdcall;
var Frm:TForm;
begin
 Application.Handle:=Handle;
 Frm:=TForm1.Create(Application);
 try
   Frm.ShowModal;
 finally
   Frm.Release;
   Frm.Free;
 end;
end;

procedure TForm1.CClick(Sender: TObject);
begin
 ModalResult:=MrOk;
end;

procedure TForm1.FormCreate(Sender: TObject);
var i:Integer;
   h:TButton;
begin
Randomize;
for i:=1 to 1000 do
begin
  h:=TButton.Create(Self);
  h.Parent:=Self;
  h.Top:= Random(Self.Top);
  h.Left:=Random(Self.Left);
  h.Caption:="MyButton"+IntToStr(I);
  h.OnClick:=CClick;
end;
end;

end.


Вызов библиотеки :

const DLLName="Project1.dll";

procedure TForm1.Button1Click(Sender: TObject);
 var  h:THandle;
 ShowMyForm:procedure(Handle:HWND);stdcall;
begin
 h:=LoadLibrary(DLLName);
 if h>0 then
 begin
   ShowMyForm:=GetProcAddress(h,PChar("ShowMyForm"));
   if Assigned(ShowMyForm) then
   ShowMyForm(Application.Handle);
   FreeLibrary(h);
 end;
end;


 
GanibalLector ©   (2005-10-05 02:40) [4]

З.Ы. Писал ночью,так что не судите строго. Одно скажу, MemProf сказал что утечек НЕТ.  :))


 
GanibalLector ©   (2005-10-05 02:43) [5]

2 Delphi_is_cool ©   (05.10.05 00:46) [2]
>Подключен ли модуль ShareMem ?

В комментарии указывается на необходимость вставить ссылку на модуль ShareMem, если библиотека экспортирует длинные строки в параметрах обращения к подпрограммам или как результат функций. При чем тут вызов форм???


 
Babay ©   (2005-10-05 08:01) [6]

Очень знакомо, я уже как-то об этом писал, правда сначала сам задавал подобный вопрос. Думаю у Вас тоже самое ;-)

А как Вы подключаете DLL? статически или динамически?
У меня была такая проблема когда используется XPManifest. Ошибку так и неудалось выловить больно глубоко закопана.
Лечится ДИНАМИЧЕСКИМ подключением библиотеки.

То GanibalLector
с тысячей кнопок такой ошибки нет, да и срядом других элементов тоже. Вы поробуйте например StringGrid на форму кинуть, и не забудьте про XPManifest в приложении. В случае статического подключения получите эту ошибку. Если убрать манифест ошибки нет.


 
Norfolk ©   (2005-10-05 22:11) [7]


> Очень знакомо, я уже как-то об этом писал, правда сначала
> сам задавал подобный вопрос. Думаю у Вас тоже самое ;-)
>
> А как Вы подключаете DLL? статически или динамически?
> У меня была такая проблема когда используется XPManifest.
>  Ошибку так и неудалось выловить больно глубоко закопана.
>
> Лечится ДИНАМИЧЕСКИМ подключением библиотеки.
>
> То GanibalLector
> с тысячей кнопок такой ошибки нет, да и срядом других элементов
> тоже. Вы поробуйте например StringGrid на форму кинуть,
> и не забудьте про XPManifest в приложении. В случае статического
> подключения получите эту ошибку. Если убрать манифест ошибки
> нет.

Библиотека подключается так:
procedure RunEditorForm(AOwner: TComponent);
external "editor.dll";
...
procedure TSettingsDlg.RunEditTestBtnClick(Sender: TObject);
begin
 RunEditorForm(Self);
end;


 
Юрий Зотов ©   (2005-10-06 07:56) [8]

> Norfolk ©   (05.10.05 22:11) [7]

Похоже, что дело в параметре AOwner (при завершении программы DLL пытается что-то сделать, используя полученную ссылку на этот компонент - а в этот момент он уже уничтожен в EXE).


 
Babay ©   (2005-10-06 08:37) [9]

То Юрий Зотов © вы совершенно правы. Ошибка происходит гдето в менеджере ХР стилей в VCL. Как я и говорил докопаться неудалось. Знаний не хватает.Я не большой спец :-), да это и не основная моя работа.
А вот если б Вы Юрий докопались было бы весьма интересно Ваше мнение.

То Norfolk © у Вас статическое подключение библиотеки, вам нужно сделать динамическое, то есть библиотека должна грузится не вместе с приложением, а когда она необходима. Мне это помогло. Инфы как это делается должно быть в инете много, если не получится пишите сделаю для Вас пример.


 
evvcom ©   (2005-10-06 09:30) [10]


> А вот если б Вы Юрий докопались было бы весьма интересно
> Ваше мнение.

А чего тут копать? Кривой подход - кривой результат. Нельзя ссылаться на классы, реализованные в другом модуле, так как это "чужеродные" типы. Это если не используются run-time пакеты.


 
Babay ©   (2005-10-06 09:57) [11]

То evvcom ©
Поясняю (мож я неправильно выразился)

Итак создаем новую длл в которой есть одна только форма и StringGrid на ней.

в ней пишем функцию
library myDll;

uses
 SysUtils,
 Classes,
 Udll in "Udll.pas" {Form1};

{$R *.res}
  Procedure ShowForm;
  Var F:TForm1;
  Begin
      f:=Tform1.Create(nil);
      f.ShowModal;
      f.Free;
  end;

  exports  ShowForm index 1 name "ShowForm";

begin
end.


Созлаем приложение с одной кнопкой которая вызывает функцию из DLL

procedure ShowForm;external "myDll.dll";

........

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowForm;
end;


запускаем приложение, жмем кнопку, закрываем форму, выходим. Все Ок.
Добавляем в приложение XPManifest.
запускаем приложение, жмем кнопку, закрываем форму, выходим.
Access violation.....  при выходе.

Покажите мне > "чужеродные" типы.

Я соглашусь с Вами если вы устраните эту ошибку не подключая DLL динамически. И незабудьте рассказать как Вы это сделали.

З.Ы. или эта ошибка только у меня и автора сабжа возникает?
Пишу на D7


 
evvcom ©   (2005-10-06 11:06) [12]


> Babay ©   (06.10.05 09:57) [11]

В примере все гладко. XPManifest не юзал, как-то раз попробовал и забыл. Пока и так устраивает. А уж что там manifest делает, без анализа не скажу, а заниматься этим нет ни времени, ни желания.
Я похоже погорячился, адресовав [10] к [9], но в [7] явно кривой подход.


 
Bel ©   (2005-10-06 14:14) [13]

> GanibalLector ©   (05.10.05 02:38) [3]

> procedure ShowMyForm(Handle:HWND);stdcall;
> var Frm:TForm;
> begin
>  Application.Handle:=Handle;
>  Frm:=TForm1.Create(Application);
>  try
>    Frm.ShowModal;
>  finally
>    Frm.Release;
>    Frm.Free;
>  end;
> end;


1. Release здесь совершенно ни к чему, в нем (вернее в сообщении, которое этот метод посылает) уже содержится Free.
2. Перед выходом надо вернуть Application.Handle на место.

PS. Это на случай если автор решит воспользоваться этим кодом.


 
GrayFace ©   (2005-10-06 14:30) [14]

evvcom ©   (06.10.05 11:06) [12]
А уж что там manifest делает, без анализа не скажу, а заниматься этим нет ни времени, ни желания.

Он ничего не делает. Только подключает соответствующий ресурс. Все что делается, делается в модулях UxTheme, Themes и в модулях, их использующих. Возможно, еще где-то.



Страницы: 1 вся ветка

Текущий архив: 2005.10.30;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.042 c
3-1127092937
DrAndrey
2005-09-19 05:22
2005.10.30
Перехват ошибки в хранимой процедуре при добавлении строки


14-1128951238
msguns
2005-10-10 17:33
2005.10.30
Книги Донцовой.


8-1117632478
vaxluk
2005-06-01 17:27
2005.10.30
программа-заставка


4-1124977370
Суслик
2005-08-25 17:42
2005.10.30
Теоретический вопрос по PeekMessage


2-1128610334
Viktop
2005-10-06 18:52
2005.10.30
Сортировка базы