Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.10.30;
Скачать: [xml.tar.bz2];

Вниз

Не закрывается приложение при работе с 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.049 c
4-1124787957
Сергей333
2005-08-23 13:05
2005.10.30
Уставновлени прав на ключ реестра для пользователя


4-1125151602
Freez
2005-08-27 18:06
2005.10.30
Узнать имя текущего процесса


14-1129093537
Ega23
2005-10-12 09:05
2005.10.30
С днем рождения! 12 октября


14-1128505443
pazitron_brain
2005-10-05 13:44
2005.10.30
Формула активного рабочего дня.


4-1124892402
NioBium
2005-08-24 18:06
2005.10.30
TrayIcon без формы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский