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

Вниз

Освобождение памяти   Найти похожие ветки 

 
wonderu   (2003-08-01 15:42) [0]

Здравствуйте!
Возникла проблема,с которой, надеюсь, Вы справитесь.
В проекте используется COM-технологии. Я пишу COM-сервер в виде DLL с главной формой, которая помещается на форме клиента. Возникает странная ситуация: приложение закрывается нормально, если не минимизировать окно клиента. После восстановления формы приложение работает нормально, но при закрытии появяется сообщение:"Access violation at adress XXXXX. Read of adress XXXXX". Помогите пожайлуста также разобрать в вопросе: куда девается память при минимизации программы?(Это видно в Диспетчере задач).
Большое СПАСИБО!
Wonder.


 
MalkoLinge   (2003-08-01 15:53) [1]

ФОрма модальная ? скорее всего нет..Как вы закрываете эту форму и освобождаете занимаемые ею ресурсы ? тут скорее всего дело не в том, минимизировано окно или нет.


 
wonderu   (2003-08-01 16:07) [2]

Форма не модальная и создается на TPanel MainForm:=TMainForm.CreateParented(WinCntr.Handle);
Ресурсы Освобождаются, но если окно не минимизировать в течение работы,то и ошибки при выходе не присходит!!!


 
MalkoLinge   (2003-08-01 16:11) [3]

Как отлаживать такие программы знаете ?


 
wonderu   (2003-08-01 16:15) [4]

Да.
Когда пишу

........
finalization
end. //<-Здесь Breakpoint

По F7 все завершается отлично!! Почему??


 
Serginio   (2003-08-01 16:19) [5]

А форма использует СОМ объект???? Дело в том, что при минимизации система забирает всю освободившуюся память. На данном форуме уже много раз эту тему обсуждали. У тебя остается ссылка на несуществующий объект, а память СОМ объекта а она выделяется через IMalloc еще остается доступной. При минимизации система может запросить о возможности выгрузки сервера если да то выгружает.
Проследи за Сом объектом вызвав отладочную информацию из Destroy, поиграйся с Inizialize.


 
wonderu   (2003-08-01 16:24) [6]

А можно поподробнее?


 
Serginio   (2003-08-01 16:31) [7]

Вернее насчет IMalloc не прав, хотя для освобождения памяти на клиенте памяти выделенной на сервере используютя функции
CoTaskMemAlloc,CoTaskMemRealloc,CoTaskMemRealloc,CoTaskMemFree}
CoTaskMemFree.

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


 
wonderu   (2003-08-01 16:44) [8]

LockServer- в Каком модуле?


 
Serginio   (2003-08-01 16:48) [9]

Смотри TComObjectFactory и реализацию интерфейсов IClassFactory, IClassFactory2


 
wonderu   (2003-08-01 16:53) [10]

Не можете подсказать ссылку на описание примеров использования TComObjectFactory(анг/рус)?


 
wonderu   (2003-08-01 16:58) [11]

Плюс ко всему прога еще использует InterBase и OpenGL(создает свои потоки),
СОМ сервер объявляется как ciSingleInstance, tmBoth.


 
Serginio   (2003-08-01 17:04) [12]

Вернее совсем не прав. Система запрашивает на выгрузку вызывая функцию из загруженной DLL "DllCanUnloadNow".

Смотри unit ComObj;

Вызывая LockServer ты сам можешь регулировать выгрузку DLL. Но СОм объекты будут уничтожаться достигнув 0 счетчика, если конечно не вызвать дополнительного _AddRef.

Плюс сюда нужно присовокупить МП и момент отбора физической памяти системой у процесса.


 
Serginio   (2003-08-01 17:08) [13]

Очень интересное объявление ciSingleInstance, tmBoth т.к
ciSingleInstance обозначает создание сервера для каждого клиента и ThreadingModel к нему вообще не применима и игнорируется.


 
wonderu   (2003-08-01 17:08) [14]

Так что же вставить в обработчик OnMinimize? Please!


 
wonderu   (2003-08-01 17:11) [15]

в клиенте

begin
CoInitFlags:=COINIT_MULTITHREADED;// Правильно ??
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TfDeviceDlg, fDeviceDlg);
Application.Run;
end.

ciSingleInstance заменить на ciMultiInstance?


 
Serginio   (2003-08-01 17:15) [16]

Во первы ты не ответил использует ли форма СОМ объект??? Если глобальные ссылки на интерфейсы Сом объекта??? В третьих в Destroy COM объекта вставь хотя бы ShowMessage (иногда правда вылетает), или другую отладочную информацию.
Просто суть такая объекта у тебя уже нет но еще не содержит ссылку (не NIL), а Delphi очень хочется вызвать _Release объекта


 
wonderu   (2003-08-01 17:23) [17]

форма использует COM объект
при создании клиента, на сервер передается указатель интерфейса обрабочика событий сервера (нажатие мыши на сервере и т.п.)

interface
uses AngelDLL_TLB,Classes,SysUtils,Windows,ComObj,ActiveX;

type
TGraphicMouseEvent = procedure (AParams: TGraphicParams) of object;
TGraphicMouseOver = procedure (const OverMessage: WideString) of object;
TGraphicProgress = procedure (const text: WideString) of object;
TAngelInterface = class(TInterfacedObject,IGraphicEvents)
private
FAngel:IAngelGraphic;//интерфейс сервера
FOnAClick: TGraphicMouseEvent;
FOnAMouseDown:TGraphicMouseEvent;
FOnAMouseOver:TGraphicMouseOver;
FOnAMouseUp: TGraphicMouseEvent;
FOnAProgress:TGraphicProgress;
FOnAError:TGraphicMouseOver;
procedure OnClick(params: TGraphicParams) ;safecall;
procedure OnMouseOver(const OverMessage: WideString); safecall;
procedure OnMouseDown(params: TGraphicParams); safecall;
procedure OnMouseUp(params: TGraphicParams); safecall;
procedure OnProgress(const text: WideString); safecall;
procedure OnError(const Error: WideString); safecall;
protected

public
procedure SetDeviceState(sdn: Integer; state: Shortint);
procedure UpdateDevice(sdn: Integer; const name: WideString; devtype: Shortint);
procedure DeleteDevice(sdn: Integer);
procedure WheelMouse(delta: Shortint);
procedure SelectPlan(plan: Integer; sdn: Integer);
procedure FindDevice(sdn: Integer);
procedure SetViewMode(mode: Shortint);
procedure PrintPlan(plan: Shortint);
procedure Resize;
procedure Disconnect;
procedure Minimize;
procedure Restore;
procedure Connect(Handle:HWND;path:string);
property OnAClick: TGraphicMouseEvent read FOnAClick write FOnAClick;
property OnAMouseDown:TGraphicMouseEvent read FOnAMouseDown write FOnAMouseDown;
property OnAMouseOver:TGraphicMouseOver read FOnAMouseOver write FOnAMouseOver;
property OnAMouseUp:TGraphicMouseEvent read FOnAMouseUp write FOnAMouseUp;
property OnAProgress:TGraphicProgress read FOnAProgress write FOnAProgress;
property OnAError:TGraphicMouseOver read FOnAError write FOnAError;
( Handle: HWND; path: string) форма использует COM объект
при создании клиента, на сервер передается указатель интерфейса обрабочика событий сервера (нажатие мыши на сервере и т.п.)

interface
uses AngelDLL_TLB,Classes,SysUtils,Windows,ComObj,ActiveX;

type
TGraphicMouseEvent = procedure (AParams: TGraphicParams) of object;
TGraphicMouseOver = procedure (const OverMessage: WideString) of object;
TGraphicProgress = procedure (const text: WideString) of object;
TAngelInterface = class(TInterfacedObject,IGraphicEvents)
private
FAngel:IAngelGraphic;//интерфейс сервера
FOnAClick: TGraphicMouseEvent;
FOnAMouseDown:TGraphicMouseEvent;
FOnAMouseOver:TGraphicMouseOver;
FOnAMouseUp: TGraphicMouseEvent;
FOnAProgress:TGraphicProgress;
FOnAError:TGraphicMouseOver;
procedure OnClick(params: TGraphicParams) ;safecall;
procedure OnMouseOver(const OverMessage: WideString); safecall;
procedure OnMouseDown(params: TGraphicParams); safecall;
procedure OnMouseUp(params: TGraphicParams); safecall;
procedure OnProgress(const text: WideString); safecall;
procedure OnError(const Error: WideString); safecall;
protected

public
procedure SetDeviceState(sdn: Integer; state: Shortint);
procedure UpdateDevice(sdn: Integer; const name: WideString; devtype: Shortint);
procedure DeleteDevice(sdn: Integer);
procedure WheelMouse(delta: Shortint);
procedure SelectPlan(plan: Integer; sdn: Integer);
procedure FindDevice(sdn: Integer);
procedure SetViewMode(mode: Shortint);
procedure PrintPlan(plan: Shortint);
procedure Resize;
procedure Disconnect;
procedure Minimize;
procedure Restore;
procedure Connect(Handle:HWND;path:string);
property OnAClick: TGraphicMouseEvent read FOnAClick write FOnAClick;
property OnAMouseDown:TGraphicMouseEvent read FOnAMouseDown write FOnAMouseDown;
property OnAMouseOver:TGraphicMouseOver read FOnAMouseOver write FOnAMouseOver;
property OnAMouseUp:TGraphicMouseEvent read FOnAMouseUp write FOnAMouseUp;
property OnAProgress:TGraphicProgress read FOnAProgress write FOnAProgress;
property OnAError:TGraphicMouseOver read FOnAError write FOnAError;
constructor Create;

published

end;

implementation

{ TAngelInterface }

procedure TAngelInterface.Connect(Handle: HWND; path: string);
begin
if assigned(FAngel) then FAngel.Connect(handle,path);
end;

constructor TAngelInterface.Create;
begin
inherited Create;
FAngel:=CoAngelGraphic.Create;
FAngel.SendGraphicEvents(self);
end;


procedure TAngelInterface.DeleteDevice(sdn: Integer);
begin
if Assigned(FAngel) then FAngel.DeleteDevice(sdn);
end;


procedure TAngelInterface.Disconnect;
//var co: IClassFactory;
begin
if Assigned(FAngel) then FAngel.Disconnect;
end;

Пожайлуста напишите свой e-mail, если это вас не затруднит


 
Serginio   (2003-08-01 17:32) [18]

Теоретически при использовании MultiInstance для объектов в DLL дает возможность использования кода DLL разными приложениями, но как на практике большой вопрос. Модель tmBoth,Free и Neutral только при синхронизации локальных данных объекта или при не изменении оных.

CoInitFlags:=COINIT_MULTITHREADED прямо сейчас не скажу но помоему применима только для серверов.
Если ты вызываешь сом объект в потоке то должен в нем отдельно вызывать CoInitialize и CoUnInitialize

Лучше найди литературу. Неполхая книга питерского издания по COM


 
wonderu   (2003-08-01 17:39) [19]

толком не разобрался, но Спасибо. Пора домой - рабочий день закончен! :-))


 
Serginio   (2003-08-01 17:40) [20]

Хорошим тоном было бы в деструкторе сделать уничтожение
FAngel:=nil. Во всяком случае можно проследить ошибку.

А мыло на моем нике.


 
Набережных С.   (2003-08-01 19:54) [21]

>Теоретически при использовании MultiInstance для объектов в DLL дает возможность использования кода DLL разными приложениями

Весьма интересная теория. Главное - очень свежая и оригинальная. К счастью, к реальности отношения не имеет.

>wonderu ©

ИМХО наилучший вариант в таких случаях - технология ActiveForm. Как отлаживать? Да как любую DLL, указав в опциях Host Application. Так-же очень удобно объединенить проекты в группу.


 
Serginio   (2003-08-01 20:04) [22]

2 (Набережных С. © (01.08.03 19:54)) Это не моя теория.
MultiInstance в DLL для меня тайна покрытая мраком. Может просвятишь????


 
Набережных С.   (2003-08-01 20:28) [23]

>Serginio (01.08.03 20:04)

В DLL этот флаг не играет роли. Собственно, эти флаги отображаются на системные REGCLS_... и влияют на то, как SCM обходится с зарегистрированными в нем фабриками. Но DLL регистрации не делают, и, сответственно, SCM на них в этом плане влиять не может. Правда, тут возникают некоторые нюансы, когда exe-хост загружает DLL, берет из нее фабрику и регистрирует ее в SCM. Но это ситуация весьма редкая и специфичная и поведение зависит еще и от флага типа сервера, использованного при регистрации в SCM. Сам я с таким вариантом знаком только только теоретически.


 
Serginio   (2003-08-01 20:39) [24]

Набережных С. © (01.08.03 20:28)
Играет особенно если посмотреть в отладчике то действительно вызываются функции в префиксом Thread, что можно судить, что каждый СОМ объект в своем потоке. Может я ошибаюсь. К сожалению нет большого опыта с W2K но там вроде под COM+ можно загружать DLL. Сейчас более подробно посмотрю в отладчике. А насчет совместного использования кода DLL в литературе как раз этим и объяснют смысл MultiInstance в DLL


 
Набережных С.   (2003-08-01 20:42) [25]

>Может я ошибаюсь.

Вот это точно.


 
Serginio   (2003-08-01 21:16) [26]

RegisterClassObject не вызывается, обратное было бы удивительно,
но при возникновении ошибки точно помню вызывался Exception c префиксом Thread.
А насчет хостов то мне это самому интересно. Попробую покапать. Если у тебя появится информация кинь пожалуйста в эту ветку или мне на мыло.


 
Набережных С.   (2003-08-01 21:29) [27]

Нет, это все-таки забавно:)


 
Serginio   (2003-08-01 21:31) [28]

Насчет чего????


 
Serginio   (2003-08-01 21:40) [29]

Я все прекрасно не понимаю. Причем в литературе такая мешанина. Если бы объект был в своем потоке, то по идее к нему нужен прозрачный прокси который уже и быдет вызывать соответствующие методы реального объекта.
У меня вопрос через какие механизмы идет вызов методов тридовых СОМ объектов (Сообщения, итд).


 
Fantasist.   (2003-08-02 01:16) [30]


> wonderu ©


Заинтересовал. Пришли мне на мыло проект, если есть возможность. Посмотреть охота.


 
Набережных С.   (2003-08-02 07:14) [31]

>Serginio (01.08.03 21:40)

Не те ты книжки читал, потому и путаница. Где-то в сети я видел перевод Дона Бокса. Поищи, не пожалеешь. Либо его же статьи в MSDN, и не только его. А книги, ориентированные на Delphi, для освоения СОМ малопригодны.
Определяющим в COM является понятие апартамента, а не потока. CoInitialize указывает SCM, в какой апартамент включить вызвавший ее поток и действует одинаково и на сервере, и на клиенте. Для синхронизации используется механизм оконных сообщений, грубо говоря SendMessage. Флаги REGCLS_*** не имеют отношения к потоковой модели, а определяют работу SCM с фабрикой. Есть свои тонкости для каждой потоковой модели, но все их пересказывать слишком длинно, лучше почитай. И, кстати, пошарь по архивам форума, здесь немало об этом говорилось.
P.S. Не удивлюсь, если модератор нас порежет к лешему, и правильно сделает. Задавать вопрос надо в отдельной ветке, а не засорять чужую. А забавно то, как ты споришь о вещах, которых не знаешь, с теми, кто с ними мал-мал знаком. Ну прям как Шариков:)


 
VaS   (2003-08-02 09:57) [32]

Поправка - в модели Free для синхронизации сообщения не используются.


 
Набережных С.   (2003-08-02 13:48) [33]

>VaS © (02.08.03 09:57)

>Поправка - в модели Free для синхронизации сообщения не используются.

Неверная поправка. Ты неверно понимаешь суть дела. Внутри любых аппартаментов синхронизация не используется. Только для пересечения границ апартаментов.


 
Serginio   (2003-08-04 15:15) [34]

Набережных С. © (02.08.03 07:14)
Дело в том, что я не спорю. Мне поросто хочется разобраться на более низком уровне. Специально открою ветку.

wonderu ©
Сделай переменную Формы переменной СОМ объекта и Destroy объекта уничтожай. Во первых у тебя будет доступ к объекту а не к интерфейсу, а во вторых может быть ситуация выгрузки DLL до уничтожения формы которая находится в этой DLL.



 
VaS   (2003-08-04 16:00) [35]


> Определяющим в COM является понятие апартамента, а не потока.
> CoInitialize указывает SCM, в какой апартамент включить
> вызвавший ее поток и действует одинаково и на сервере, и
> на клиенте. Для синхронизации используется механизм оконных
> сообщений, грубо говоря SendMessage.



> Ты неверно понимаешь суть дела. Внутри любых аппартаментов
> синхронизация не используется.


Из твоего первого сообщения не очевидно, что идет речь об апартаментах. Я имел в виду, что в модели Free нужно использовать другие методы синхронизации доступа клиентов к ком-объектам, а не предоставляемые COM.


 
Serginio   (2003-08-04 16:25) [36]

Полностью согласен с Набережных С. © (01.08.03 19:54) на счет ActiveForm правда иногда бывает мало пригодна особенно когда нужно вызвать из объекта различные диалоговые окна и нужен полный доступ к объекту а не к интерфейсам.


 
Набережных С.   (2003-08-04 19:00) [37]

>VaS © (04.08.03 16:00)

Видимо, ты прав. Действительно, не четко, мой грех:)



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

Форум: "Потрепаться";
Текущий архив: 2003.08.18;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.55 MB
Время: 0.004 c
14-58406
artgamer
2002-12-12 23:56
2003.08.18
Караул!!! Не могу запустить приложение MCK!!!


14-58420
grusty
2003-08-03 11:37
2003.08.18
DBTreeView для ADO.


14-58426
Best Gun
2003-08-02 19:26
2003.08.18
Обновления для Win2000 + SP4


14-58496
dez
2003-08-04 20:15
2003.08.18
Как не дать мыше уйти с компонента


14-58423
NNN
2003-08-02 18:03
2003.08.18
REGISTRACIJA PROGRAMM





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