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

Вниз

Ошибка после нескольких вызывов MCK формы из DLL   Найти похожие ветки 

 
Delphuk ©   (2007-07-02 13:32) [0]

Добрый день. Возникла проблема, при использовании 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]

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


 
vpbar   (2007-07-02 14:22) [1]

см
http://kolmck.net/demos/DemoVCL2KOLDLL.zip и http://kolmck.net/demos/Demo2NonModalFormsDLL.zip


 
=BuckLr=   (2007-07-02 15:02) [2]

Delphuk, совершенно верно насчёт освобождений и глюков. Я имел некоторый опыт с вызовом формы из длл. Я использовал такой вызов:


 Applet := NewApplet("");
 Applet.Hide;
 NewMainForm(MainForm, Applet);
 MainForm.Form.ShowModalEx;
 MainForm.Form.Free;
 MainForm := nil;
 Free_And_Nil(Applet);


Это приводило к тому, что на FreeLibrary в хост-программе вылазило AV. Когда я стал освобождать библиотеку не сразу после использования, а на OnDestroy программы, ошибок доступа не появлялось. Но это ещё ничего. Самая большая бага происходила тогда, когда я вызывал форму не модально, а встраивал её в окно программы (в хост приложении была предусмотрена такая возможность, и так делалось на всл). Если на форме в длл находился какой-нибудь эдит-контрол, то не работали клавиши влево-вправо, хоть убей. Я так и не разобрался, в чём там дело. Решил проблему (ржать будете, но делать нечего) выносом формы в отдельный поток. Это сработало. А про неосвобождённую память я вообще молчу. Короче, так я и не разобрался, ибо я не программист, а лишь любитель. И для меня эта тема уже не так актуальна. Хотя может быть кто-то из просветлённых покопается и найдёт багу...


> см
> http://kolmck.net/demos/DemoVCL2KOLDLL.zip и http://kolmck.
> net/demos/Demo2NonModalFormsDLL.zip


Это всё хорошо, но, насколько я понимаю, товарищу нужно использовать динамическую загрузку, а в этих примерах статическая. Ведь делается плагин, а не что-то иное...


 
vpbar   (2007-07-02 15:36) [3]

Вопрос был не в том как динамически подгрузить dll. Я думаю товарисч это умеет. А в остальном вызовы функций из динамически подгруженной и статически(кстати это не совсем верно длл все равно подгружается динамически но уже загрузчиком) происходят одинково и с одинаковыми последствиями.


 
Delphuk ©   (2007-07-02 16:06) [4]

Всех благодарю за ответы. Прежде чем вообще писать плагин, я конечно же ознакомился с FAQ по работе KOL+MCK в DLL. Да и работать с библиотеками конечно же я умею :)
vpbar писал:
<quote>см
http://kolmck.net/demos/DemoVCL2KOLDLL.zip и http://kolmck.net/demos/Demo2NonModalFormsDLL.zip</quote>

Эти демки я конечно же уже смотрел и писал по аналогии, сейчас даже чуть чуть переделал код:

procedure OnPreferences;
var
SettingsForm: PSettingsForm;
begin
if not Assigned(SettingsForm)
then
  begin
   Applet := NewApplet("AMG");
   Applet.Hide;
   NewSettingsForm(SettingsForm, Applet);
   SettingsForm.Form.ShowModalEx;
   SettingsForm.Form.Free;
   SettingsForm := nil;
   Free_And_Nil(Applet);
   AppletTerminated := false;
 end;
end;


Но это не решает проблем. По прежднему память освобождается не полностью и после каждого вызова и закрытия модальной формы, в памяти прибавляется по 4кг, после 7-го вызавов формы, появляется ошибка! После чего форма вообще больше не вызывается.

vpbar, ради спортивного интереса, я скачал думку http://kolmck.net/demos/DemoVCL2KOLDLL.zip скомпилил и проверил как она будет работать. И что вы думаете? :) В этой демке точно такая же проблема, только память вообще не освобождается (в моём плагине всё же освобождает 20 кг, но всё равно есть утечка) и после 5-го или 6-го вызова формы, вылетает ошибка, после чего форма конечно же уже не показывается. Так что похоже есть какие то ошибки в KOL или я, =BuckLr=, создатель демок и тд что то неправильно делаем :(

=BuckLr=, ты написал тоже самое, но всё равно спасибо за отзывчивость и понимание.


 
Delphuk ©   (2007-07-02 16:10) [5]

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


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

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

{ 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;

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


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

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

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


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

Сорри. Торможу.
Там в дллке есть еще 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 при загрузке длл. И уничтожается только при закрытии приложения.


 
Delphuk ©   (2007-07-02 17:13) [9]


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

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


 
Delphuk ©   (2007-07-02 17:38) [10]

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;


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

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


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


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

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

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

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


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

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

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


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

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

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


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

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


 
Delphuk ©   (2007-07-02 23:31) [16]


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

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


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


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

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


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

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


 
Delphuk ©   (2007-07-03 20:59) [19]

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


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

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

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


 
Delphuk ©   (2007-07-03 22:07) [21]

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


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

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

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


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

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


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

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

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



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

Форум: "KOL";
Текущий архив: 2008.03.09;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.53 MB
Время: 0.042 c
4-1184224151
DelphiN!
2007-07-12 11:09
2008.03.09
RunAs программы под SYSTEM-ом не работает


15-1201827329
Tirael
2008-02-01 03:55
2008.03.09
вопрос по Wget


8-1176707946
Jeer
2007-04-16 11:19
2008.03.09
Метод распознавания эффекта красных глаз


10-1144044391
Alex_C
2006-04-03 10:06
2008.03.09
предупреждение при закрытии COM-serv


2-1202585855
Петр
2008-02-09 22:37
2008.03.09
проверка строки на символы





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский