Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Ошибка после нескольких вызывов MCK формы из DLL [Delphi, Windows]


Страницы:   1 2

Delphuk ©   (2007-07-02 13:32:00) 

Добрый день. Возникла проблема, при использовании KOL+MCK в dll. Я пишу плагин для программы, и решил использовать KOL+MCK для создания интерфейса. У меня имеется только одна форма (для настроек плагина), вызываю я её следующим образом:
[code]
procedure OnPreferences;
begin
if SettingsForm = nil
then
  begin
   Applet := NewApplet('AMG');
   NewSettingsForm(SettingsForm, Applet);
   SettingsForm.Form.ShowModal;
   SettingsForm.Form.Free;
   SettingsForm := nil;
   Applet.Free;
  end;
end;
[/code]

После нескольких вызывов данной формы, вылетает ошибка. Ещё я заметил, что при вызове методов Free память не освобождается и объект не уничтожается. Сначала я использовал вот такой вариант:

[code]
procedure OnPreferences;
begin
if not Assigned(SettingsForm)
then
  begin
   Applet := NewApplet('AMG');
   NewSettingsForm(SettingsForm, Applet);
   SettingsForm.Form.ShowModal;
   SettingsForm.Form.Free;
   SettingsForm.Free;
   Applet.Free;
  end;
end;
[/code]

Но после закрытия формы память не освобождается. К тому же повторно окно настроек уже не открывается.
Пожалуйста подскажите, как нужно правильно написать этот фрагмент кода.


=BuckLr=   (2007-07-18 13:23:00) [1]

Нет, не делал. Я с Си не дружу. За пример спасибо, посмотрю, что к чему.
Но интересует главным образом чисто логический вывод - если ваш пример не падает, а та прога падает, значит, такая прога? Она вообще странная :) Вот например, если я показываю форму модально (код вызывающей процедуры взял прямо из вашего демо), то когда форма закрывается, то всё тип-топ. А когда закрываю хостовую прогу, то она валится. Если же показываю форму немодально, то форма появляется и сразу исчезает.

Короче, если сегодня вечером, с пивом, не разберусь, в чём там дело, то забью на всю эту бодягу :)


Vladimir Kladov   (2007-07-17 17:22:00) [2]

А вы сами С-проект делали? Я положил свой вариант в виде rar-архива прямо внутрь того же демо. Учтите, что на С я давно не программировал, не помню, как получать со строками работать, и чтобы не вспоминать, все пути абсолютные. В том числе в настройках проекта - output для Debug. Всё работает, ничего не падает, я даже не перекомпилировал dll с последнего раза.


=BuckLr=   (2007-07-16 23:16:00) [3]

Попробовал сделать дллку с формой используя код этого нового демо. Длл цепляется сишной программой и потом вызывается форма. И вот что странно - в случае с VCL работает, а в случае с этой прогой - хост прога вылетает на строчке Applet.Free;

В чём тут дело? В всл же работает, и отлично работает. Может такая прога,, что криво работает с моей дллкой?


Delphuk   (2007-07-03 22:07:00) [4]

Спасибо за помощь.


Vladimir Kladov   (2007-07-03 22:03:00) [5]

Автоматически апплет создаётся не в расчёте на несколько вызовов. Для этого случая надо его создавать для каждого вызова отдельно, и не в begin...end самой dll, а в экспортируемой функции. Потому и добавил код для убивания общего Applet'а.

Кстати, сейчас закачиваю ещё другой вариант, там пара изменений: можно поставить или отключить символ MODAL, для немодального нужен контроль единичного вызова. Два раза и больше так вызывать нельзя - глобальный Applet мешается.


Delphuk   (2007-07-03 20:59:00) [6]

Vladimir Kladov, спасибо, теперь всё работает. В вашей новой демке несколько проектов DLL, я так понял, что все файлы KOLDll* это лишнее. Правильно? Ещё возникли вопросы, зачем в нескольких местах создавать Applet?


Vladimir Kladov   (2007-07-03 17:12:00) [7]

Ладно, еще раз заброшу. 182К должно быть.


BuckLr   (2007-07-03 11:30:00) [8]


> Ктати это не совсем верно длл все равно подгружается динамически
> но уже загрузчиком

Ну так то оно так, не суть важно, но разница всё же есть... Но дела не меняет - с динамическим подключением глюки. Сейчас новую демку попробую глянуть


Delphuk   (2007-07-02 23:31:00) [9]


> jeks   (02.07.07 23:06) [15]
> DemoVCL2KOLdll.zip - corrupted archive. Видать, таки не
> обновилось.

+1 хотел посмотреть на новую демку, скачал архив, а он битый. При распаковке выдаёт ошибку.


jeks   (2007-07-02 23:06:00) [10]

DemoVCL2KOLdll.zip - corrupted archive.
Видать, таки не обновилось.


Vladimir Kladov   (2007-07-02 19:59:00) [11]

Сейчас обновлю DemoVCL2KOLdll. На всякий случай (хостинг у нас теперь щедрее, спасибо Тэду), скомпилированные exe и dll там же. Есть опция STATIC_LINKAGE (в части VCL). Работают одинаково. Утечки если есть - только на стороне VCL (MemProof ругается 10 раз, независимо от числа вызовов). На стороне dll MemProof видит только отсутствие затребованного ресурса и некоторое число попыток освобождения несуществующего ресурса. Ошибки на выходе в новом варианте нет.

Пока писал, уже обновилось.


vpbar   (2007-07-02 19:36:00) [12]

Понято. Просто вполен возможно что утечка не связана с тем как вызывается форма. Хотя если там кроме этого нет ничего, то хз.

Линк не помню. В проге есть ссылка на этот сайт
http://www.automatedqa.com/.
Могу выслать по почте (оно Free).
Есть еще альтернативный менеджер памяти для Делфи с анализом утечек памяти http://v.mahon.free.fr/pro/freeware/memcheck


Delphuk   (2007-07-02 19:12:00) [13]


> Еще уточнение вы вызываете плагин из своего приложения или
> из левого? В смысле какие ему еще параметры передаются?

Приложение не моё, я только пишу плагин (плагин для программы RnQ). Ему ещё много чего передаётся, но само приложение с окном настроек никак не связано. Утечка памяти именно в том месте, где вызывается форма (код этой процедуры я уже писал). Я только начал писать этот плагин, так что никакого кода, кроме показа окна формы нет (за исключением кода инициализации плагина в приложении).

> По поводу утечки памяти есть инструмент memprof и еще один
> (Забыл как называется но если заитересует могу посмотреть),
>  которые выявляют  факт и место утечки ресурсов.

Буду рад, если вы напишите название этой тузлы (или линк на скачку), думаю в будущем пригодится.


vpbar   (2007-07-02 19:00:00) [14]

Ну незнаю. Просто то что я дал по ссылке http://kolmck.net/demos/DemoVCL2KOLDLL.zipи то что есть и работает у меня - это как оказалось разные демки. У меня все работает (жал раз 15 не вылетает и память не утекает) А то что скачал по ссылке глючит. Хотя в свое время я вроде оттуда демку и скачивал. Хз. Може ее заменили.
Могу выслать то что у меня работает.
Еще уточнение вы вызываете плагин из своего приложения или из левого? В смысле какие ему еще параметры передаются?
По поводу утечки памяти есть инструмент memprof и еще один (Забыл как называется но если заитересует могу посмотреть), которые выявляют  факт и место утечки ресурсов.


Delphuk   (2007-07-02 17:38:00) [15]

vpbar писал:

> Т.е. в моем примере создается  Applet при загрузке длл.
> И уничтожается только при закрытии приложения.


Сделал аналогично, а не в процедуре вызова формы. Проблема с ошибкой после многократного вызова формы исчезла, но утечка памяти осталась. После первого показа формы добавляется где то 40 кг, после закрытия формы, память не освобождается. Далее, после каждого показа формы добавляется по 4кг :(


procedure OnPreferences;
begin
if not Assigned(SettingsForm)
then
  begin
   NewSettingsForm(SettingsForm, Applet);
   SettingsForm.Form.ShowModalEx;
   SettingsForm.Form.Free;
   SettingsForm := nil;
 end;
end;


Delphuk   (2007-07-02 17:13:00) [16]


> vpbar   (02.07.07 16:58) [7]
> >>> =BuckLr=  Applet := NewApplet(''); Applet.Hide; NewMainForm(MainForm,
>  Applet);Зачем создавать Applet если тут же скрывать его?
> ?

В демке точно так же. Зачем это я не знаю :) но на всякий случай тоже добавил. vpbar, у меня всё аналогично твоему коду. Форму нужно вызывать модально, она появляется, всё чудесно. Закрывается - тоже классно :) Потом опять открываем её, тоже всё оки, и так же закрываем. И вот если сподряд так 7 раз открыть и закрыть, то на 8-й раз вылетает ошибка и больше ничего не показывается. В предложенной тобою демке присутствуют все теже проблемы.


vpbar   (2007-07-02 17:10:00) [17]

Сорри. Торможу.
Там в дллке есть еще KOLDLL_0.inc
такой

{ KOL MCK } // Do not remove this line!
{ KOLDLL_0.inc
 Do not edit this file manually - it is generated automatically.
 You can only modify KOLDLL_1.inc and KOLDLL_3.inc
 files. }
{$IFDEF Pcode}
InstallCollapse;
{$ENDIF Pcode}
 Applet := NewApplet( 'KOLDLL' );
 Applet.GetWindowHandle;
 Applet.Visible := False;
{$I KOLDLL_1.inc}
{$I KOLDLL_2.inc}
{$I KOLDLL_3.inc}
{$I KOLDLL_4.inc}

Т.е. в моем примере создается  Applet при загрузке длл. И уничтожается только при закрытии приложения.


vpbar   (2007-07-02 16:58:00) [18]

>>> =BuckLr=
Applet := NewApplet('');
Applet.Hide;
NewMainForm(MainForm, Applet);

Зачем создавать Applet если тут же скрывать его??


vpbar   (2007-07-02 16:44:00) [19]

Учточню. Форму надо модально показывать или нет? Если модально то вот вариант  вариант который работает у меня

{ KOL MCK } // Do not remove this line!
library KOLDLL;
uses
KOL,  KOLUnit1 in 'KOLUnit1.pas' {KOLForm1};
exports
 CallKOLFormModal name 'CallKOLFormModal';
//{$R *.res}
begin // PROGRAM START HERE -- Please do not remove this comment
{$IFDEF KOL_MCK} {$I KOLDLL_0.inc} {$ELSE}
 Application.Initialize;
 Application.Run;
{$ENDIF}
end.



{ KOL MCK } // Do not remove this line!
{$DEFINE KOL_MCK}
unit KOLUnit1;
interface
{$IFDEF KOL_MCK}
uses Windows, Messages, ShellAPI, KOL {$IFNDEF KOL_MCK}, mirror, Classes,
 Controls, mckCtrls {$ENDIF};
{$ELSE}
{$I uses.inc}
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 mirror;
{$ENDIF}

type
 {$IFDEF KOL_MCK}
 {$I MCKfakeClasses.inc}
 PKOLForm1 = ^TKOLForm1;
 TKOLForm1 = object(TObj)
   Form: PControl;
 {$ELSE not_KOL_MCK}
 TKOLForm1 = class(TForm)
 {$ENDIF KOL_MCK}
   KOLProject1: TKOLProject;
   KOLForm1: TKOLForm;
   Button1: TKOLButton;
   KOLApplet1: TKOLApplet;
   procedure Button1Click(Sender: PObj);
 private
   { Private declarations }
 public
   { Public declarations }
 end;
var
 KOLForm1 {$IFDEF KOL_MCK} : PKOLForm1 {$ELSE} : TKOLForm1 {$ENDIF} ;
procedure CallKOLFormModal; export;
{$IFDEF KOL_MCK}
procedure NewKOLForm1( var Result: PKOLForm1; AParent: PControl );
{$ENDIF}
implementation

{$IFNDEF KOL_MCK} {$R *.DFM} {$ENDIF}
{$IFDEF KOL_MCK}
{$I KOLUnit1_1.inc}
{$ENDIF}
procedure CallKOLFormModal;
begin
 NewKOLForm1( KOLForm1, Applet );
 KOLForm1.Form.ShowModal;
 KOLForm1.Form.Free;
 KOLForm1 := nil;
end;
procedure TKOLForm1.Button1Click(Sender: PObj);
begin
 Form.ModalResult := 1;
 Form.Close;
end;
end.

{ KOL MCK } // Do not remove this line!
Ну и KOLUnit1_1.inc:

procedure NewKOLForm1( var Result: PKOLForm1; AParent: PControl );
begin
 New( Result, Create );
 Result.Form := NewForm( AParent, 'KOLForm1' ).SetPosition( 254, 243 ).SetSize( 255, 251 );
 Result.Form.Add2AutoFree( Result );
   // Result.Button1.TabOrder = 0
   Result.Button1 := NewButton( Result.Form, 'Close' ).SetPosition( 64, 80 ).SetSize( 121, 0 );
     Result.Button1.OnClick := Result.Button1Click;
end;

Если немодально то там чуть побольше кода


Delphuk   (2007-07-02 16:10:00) [20]

P.S.
Я использую Windows XP SP2, KOL+MCK 2.72, Delphi 6.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо