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

Вниз

COM. Правильная инициализация/закрытие   Найти похожие ветки 

 
_VaaL_   (2003-09-12 10:19) [0]

Где правильно прописывать методы инициализации/закрытия при создании COM компонента? Не хотелось бы вызывать дополнительные собственные методы Init и Close. Хотелось бы чтобы при создании обьекта он сам себя инициализировал. Какие методы перекрывать / куда что дописывать? (Instancing - Multiple instance, Threading Model - Single).
Спасибо


 
Nikolay M.   (2003-09-12 10:28) [1]

Мнээ...
Секции initialization/finalization не подходят?


 
_VaaL_   (2003-09-12 10:38) [2]

А это будет правильно?
DllGetClassObject, DllCanUnloadNow, DllRegisterServer, DllUnregisterServer - то функции которые нужны для работы обьекта. Насколько я понимаю обект еще не создан когда библиотека загружена. Обьект создает TAutoObjectFactory.
Насколько я понимаю поочередность загрузки такова:
1. Загружается DLL
2. INITIALIZATION
3. TAutoObjectFactory.Create

Выгрузка:

1. Освобождение Обьекта.
2. FINALIZATION.

Если я прав то initialization/finalization не подходят, если нет - буду рад если меня поправят.


 
_VaaL_   (2003-09-12 11:49) [3]

Оказывается, если использовать разделы initialization/finalization, то компиляция проэкта проходит без проблем, а вот регистрация - вылетает. Посему вопрос появляется еще один - почему?


 
icWasya   (2003-09-12 12:10) [4]

а что значит - сам себя инициализировал?
вообще говоря есть метод Initialize - именно он вызывается при создании COM объекта. а для уничтожения - обычный Destroy
или надо что-то ещё ??


 
_VaaL_   (2003-09-12 12:14) [5]

Тоесть для инициации моих переменных мен нужно перекрыть Initialize и Destroy? Счас попробую...


 
icWasya   (2003-09-12 12:18) [6]

и не забывай про inherited


 
_VaaL_   (2003-09-12 12:26) [7]

procedure TСlassName.Initialize;
begin
inherited Initialize;
MyUnit.Init;
end;

Destructor TСlassName.Destroy;
begin
MyUnit.Quit;
inherited Destroy;
end;

Пишет Catastrophic Failure :(


 
_VaaL_   (2003-09-12 12:33) [8]

Теперь этот обьект даже создаватся нормально не может. Очень неохота выводить процедуры инициализации/закрытия в отдельные методы COM обьекта.
Идеальный вариант:
x:=CreateComObject(CLASS_Blablabla) as IBlablabla; // все уже инициировано можна приступать к работе
....
x:=NIL; // обьект освобожден, память под переменные - тоже


еще добавлю что процедуры моего модуля стопроцентно рабочие так как тестировались в отдельном проэкте.


 
Юрий Федоров   (2003-09-12 12:40) [9]

>>procedure TСlassName.Initialize;

override не забыл ?
Если не забыл, то написано все правильно


 
_VaaL_   (2003-09-12 12:52) [10]

>>Юрий Федоров ©
>>override не забыл ?
Не забыл.

Нащет перекрытия Initialize - это стандартный прием в COM-програмировании или просто совет навскидку?


 
icWasya   (2003-09-12 13:08) [11]

совет на основе личного опыта и анализа исходников VCL
а по-подробнее, что именно делается в MyUnit.Init ??


 
_VaaL_   (2003-09-12 13:19) [12]

В MyUnit.Init создается обект DOMDocument для загрузки определенных данных в динамический массив из XML документа.

var
XML: Variant;
...
XML:=CreateOLEObject("Msxml2.DOMDocument");
XML.Async:=false;
XML.Load(s);
...
Загрузка данных в динамический массив
...
XML:=varNULL; //освобождение обьекта DOMDocument


После этого массив сортируется для более быстрого поиска. Вот и все.

Еще одна процедура освобождает память динамического массива и должна вызыватся в конце.

Вот терерь это все нада всунуть в разделы инициализации/освобождения COM обьекта.


 
Юрий Федоров   (2003-09-12 13:35) [13]

MyUnit.Init, вызванный сам по себе (не в инициализации COM-объекта), не приводит к падению?
Если так, то возможно собака порылась где-то в CoInitFlags


 
_VaaL_   (2003-09-12 13:46) [14]

Нет, не приводит. Я модуль MyUnit тестировал в отдельном приложении до токо как писать COM обьект.
Фабрика класов создает мой обьект так :

TAutoObjectFactory.Create(ComServer, TMyCOMComponent, Class_Blablabla, ciMultiInstance, tmSingle);

Может я использую неправильную модель? (хотя врядли..). Поидее CoInitFlags устанавливается в зависимости именно от этой команды (так хелп говорит).


 
_VaaL_   (2003-09-12 15:24) [15]

А в ответ тишина... :)


 
Nikolay M.   (2003-09-12 15:56) [16]


> var
> XML: Variant;

- глобальная переменная или она принадлежит СОМ-объекту?
Если первое, то хочется напомнить свой первый пост :)
Если второе - то будет ли происходить Catastrophic failure, если закомментировать MyUnit.Init/MyUnit.Quit?


 
nikkie   (2003-09-12 15:57) [17]

ты вызов своего Init поставь под try...except


 
Юрий Федоров   (2003-09-12 15:59) [18]

кроме того
1. Создается ли COM-объект (я так понял, что имеем дело с InProc Server) в основном потоке приложения или в дополниьельном.
2. С какими параметрами происходит вызов CoInintializaEx в вызывающем приложении (для этого потока)


 
_VaaL_   (2003-09-12 16:16) [19]

XML - локальная перменная процедуры Init. Тоесть первое отпадает. А вот второе - ничего непадает, если обьект не инициализируется в методе Initialize, хотя если запускать в другом проэкте то процедура Init работает нормально... странно.


 
_VaaL_   (2003-09-12 16:23) [20]

Я закоментировал секцию работы с XML - инициация прошла успешно (покрайней мере без видиміх проблем). Значит я неправильно работаю с XML. Выше я приводил пример инициации COM обьекта DOMDocument. Я что, создаю/удаляю его неправильно?
var
XML: Variant;
...
XML:=CreateOLEObject("Msxml2.DOMDocument");
XML.Async:=false;
XML.Load(<filename>);
...
XML:=varNULL;


 
Polevi   (2003-09-12 16:27) [21]

>_VaaL_ (12.09.03 16:23) [20]
возможно плохой xml документ, парсер предоставляет информацию об ошибках парсинга, проверь


 
Юрий Федоров   (2003-09-12 16:29) [22]

Отладчик не работает?
Какой-то Exception поднимается при работе с XML, только и всего. Если узнать, какой именно - все сразу станет ясно


 
Nikolay M.   (2003-09-12 16:30) [23]

А в коде выше еще написана какая-то "Загрузка данных в динамический массив" - там что?


 
_VaaL_   (2003-09-12 16:38) [24]

>>Юрий Федоров © (12.09.03 16:29) [22]
Отладчик не работает?
Да в том то и дело что при использовании в любом другом проекте ексепшенов нету :(. А как я могу отладить DLL пошагово? - вроде никак. :(

Nikolay M. © (12.09.03 16:30) [23]
А в коде выше еще написана какая-то "Загрузка данных в динамический массив" - там что?

Простой разбор XML, установка размера для динамического массива и заполнение данными из XML документа


 
_VaaL_   (2003-09-12 16:43) [25]

Polevi © (12.09.03 16:27) [21]
не может он быть ошибочным так как открывается через експлорер. DTD схем нету.


 
Nikolay M.   (2003-09-12 16:55) [26]


> Простой разбор XML, установка размера для динамического
> массива и заполнение данными из XML документа

А если это все закомментировать?
Если все ок, тогда правы

> Polevi © (12.09.03 16:27) [21]
> Юрий Федоров © (12.09.03 16:29) [22]


 
_VaaL_   (2003-09-12 16:59) [27]

Nikolay M. © (12.09.03 16:55) [26]
Я коментировал. И все работало хорошо. Но тогда почему та же процедура без проблем работает в отдельном проэкте (никаких ексепшенов)?


 
Nikolay M.   (2003-09-12 17:07) [28]

А код большой?
Кинь сюда, неохота на кофейной гуще гадать :)


 
_VaaL_   (2003-09-12 17:21) [29]


type
TStoredProc = record
Name: string;
Params: array of string;
Request: string;
end;
var
SP: array of TStoredProc;
....
....
XML:=CreateOLEObject("Msxml2.DOMDocument");
XML.Async:=false;
XML.Load(s);
Root:=XML.DocumentElement;
if Root.HasChildNodes then
begin
Count:=Root.ChildNodes.Length;
SetLength(SP, Count);
for i:=0 to Root.ChildNodes.Length - 1 do
begin
SPNode:=Root.ChildNodes.Item(i);
SP[i].Name:=SPNode.NodeName; // Getting Name
SPParams:=SPNode.ChildNodes.Item(0); // Getting Parameters
if SPParams.HasChildNodes then
begin
Count:=SPParams.ChildNodes.Length;
SetLength(SP[i].Params, Count);
for j:=0 to SPParams.ChildNodes.Length - 1 do
begin
SPPar:=SPParams.ChildNodes.Item(j);
SP[i].Params[j]:=SPPar.NodeName;
end;
end;
SPParams:=SPNode.ChildNodes.Item(1); // Getting Request
SPPar:=SPParams.ChildNodes.Item(0);
if SPPar.NodeType = 4 /*CDATA*/ then
SP[i].Request:=SPPar.NodeValue;
end;
end;
XML:=varNULL; // Closing XML Object


Здесь:
XML, Root, SPNode, SPPar: Variant;
SP - структура которая заполняется из XML

Пример XML:
<?xml version="1.0" encoding="utf-8"?>
<root>
<test>
<params>
<id/>
<name/>
</params>
<request>
<![CDATA[Select <[name]> from Main_Menu where mm_id=<[id]>;]]>
</request>
</test>
</root>


 
Nikolay M.   (2003-09-12 17:25) [30]

Хм. Сразу бросается в глаза, что TStoredProc - имя уже объявленного класса в DBTables... Этот модуль нигде не подключается?


 
_VaaL_   (2003-09-12 17:27) [31]

Nikolay M. © (12.09.03 17:25) [30] нет. Здесь вообще нет подключения к какой бы то нибыло БД


 
Erik   (2003-09-12 18:13) [32]

"А как я могу отладить DLL пошагово? - вроде никак. :("
Если это без проблем отлаживается! Идем в Run/Parametrs
Там заполняем Host Application - кот вызывает твою dll.
И отлаживай себе на здорове. Но если проблема серездная, то врядли тебе здесь ответят. Com вобще дело темное.


 
Юрий Федоров   (2003-09-12 18:13) [33]

Насчет отладчика - можно отлаживать DLL без проблем.
после помещения Exe и DLL в одну группу проектов и перебилда обоих отладчик ходит насквозь...
я на 90 процентов уверен, что дело в каком-то конфликте, связанном с флагами инициализации COM (конфликт поточных моделей).
Ты не пробовал поставить ThreadingModel = tmApartment?

В общем, один запуск прорраммы подл отладчиком - и ответ на вопрос будет получен...


 
Serginio666   (2003-09-12 18:55) [34]

Помоему сам нарывался на ThreadingModel = tmApartment. Работает только в TComponentFactory. Да и для DLL это не играет роли если не нужен маршалинг.
Лучше поставь проинициализируй как MTA, т.к. c STA куча проблем.


 
Юрий Федоров   (2003-09-12 19:04) [35]

>>Serginio666 (12.09.03 18:55) [34]
С апартаментами проблемы только с Local Server, с InProc все должно быть нормально.
Да и лечится легко, путем небольшого потомка от фабрики классов...


 
Serginio666   (2003-09-12 19:25) [36]

Это я знаю, сам создавал,проверял. Да и для Inproc сервера ThreadingModel = tmApartment не играет никакой роли без TApartmentThread передается прямая ссылка на объект.
Может проблема в
http://www.rsdn.ru/article/atl/atlsingleton.xml

"Проблема маршалинга синглтона в фабрике классов также весьма актуальна для внутрипроцессных серверов, так как клиенты запросто могут находиться в разных апартаментах, и все клиенты будут получать прямую ссылку на синглтон. Для синглтонов с потоковой моделью Apartment это может означать, что вызовы могут приходить из других потоков. Без синхронизации все закончится плачевно, а клиенты даже не будут ничего подозревать, так как имеют дело не с proxy, а с прямым указателем, и ошибку RPC_E_WRONGTHREAD, означающую, что вызов был сделан из “неподходящего” потока, им никто не вернет."


 
Serginio666   (2003-09-12 19:52) [37]

Да еще очень плохо работать в СОМ с глобальными переменными.
Разве нельзя
Внести все в объект и работать с полем объекта.
procedure TСlassName.Initialize;
begin
inherited Initialize;
XML:=CreateOLEObject("Msxml2.DOMDocument");
end;

Destructor не нужен.


 
_VaaL_   (2003-09-17 13:51) [38]

Короче, помудрил я и понял, что всетаки проблема тут в создании Msxml2.DOMDocument такое впечатление что когда я вызываю CreateOLEObject("Msxml2.DOMDocument") то еще небыла вызывана CoInintialize, хотя модуль ComObj стоит в Uses...
Поэтому решил хранить загружаемые данные в простых файлах. После этого все начало работать без проблем.
Спасибо всем кто помогал разбиратся с этим делом.


 
Erik   (2003-09-18 14:37) [39]

А я то думаю, чего у меня глючит завершение InProc сервера! ThreadingModel = tmApartment стоит хотел поменять да так и оставил. А маршалинг у меня есть и выгружается коректно только в случаее с Exe сервером.



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

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

Наверх





Память: 0.54 MB
Время: 0.011 c
1-3973
Evg12
2003-09-19 13:02
2003.10.02
Обработка Нажатия Escape


1-3887
komissar
2003-09-18 15:11
2003.10.02
DesignIDE


1-3861
Berezne
2003-09-17 11:28
2003.10.02
Подстановка в Combobox


7-4152
volser
2003-07-17 19:57
2003.10.02
Координаты мышки


14-4087
raper
2003-09-14 17:11
2003.10.02
Простите но мой вопрос касаеться винды





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