Re[2]: Как запустить COM в другом потоке?
От: Alex Fedotov США  
Дата: 18.10.01 18:46
Оценка: 2 (1)
Здравствуйте The Lex, Вы писали:

К>>При отладке — сообщение что-то типа "MYServer.dll relocated due to collision with Some.dll..."

TL>Совет номер 2: не обращай мнимания на это сообщение: у меня COM-DLL-ек штук по пять-шесть грузится и на каждую он пишет подобные страшные вещи. Что означают — не знаю — это, вон, к гуру. Знаю что на это можно не обращать внимания.

Это сообщение говорит о том, что DLL не может быть расположена в адресном пространстве процесса по своему предпочтительному базовому адресу, потому что это место уже занято (другой DLL или чем-то еще). Загрузчик вынужден переместить DLL в адресном пространстве процесса, что приводит к использованию дополнительного пространства в pagefile и, если более одного процесса используют эту DLL, к большему использованию физической памяти. При создании своих DLL следует стремиться к тому, чтобы они все находились по уникальным базовым адресам и не конфликтовали с другими DLL, для чего служат ключ линкера /BASE и утилита rebase.

Cмотри также:
Rebasing Win32 DLLs: The Whole Story
http://msdn.microsoft.com/library/en-us/dndllpro/html/msdn_pagetest.asp
-- Alex Fedotov
Как запустить COM в другом потоке?
От: Константин  
Дата: 18.10.01 13:29
Оценка:
Сделал простейший COM-Server.
В клиентском MFC-приложении запускаю поток — класс, производный от CWinThread. В его InitInstance делаю СoInitialize и пытаюсь получить доступ к своему Server-у, используя SmartPointer-ы. В ответ — сообщение об ошибке (Invalid pointer = 0).При отладке — сообщение что-то типа "MYServer.dll relocated due to collision with Some.dll..."
Если все делать в рамках главного потока программы — все ОК (сообщение о collision). Но мне нужно иметь доступ к COM внутри другого потока.
Re: Как запустить COM в другом потоке?
От: Willi  
Дата: 18.10.01 14:06
Оценка:
Здравствуйте Константин, Вы писали:

Скорее всего проблема с потоковыми моделями.
На этом сайте есть первод хорошей статьи
посвященной многопотоковому COM программированию

http://www.rsdn.ru/article/?com/apartmnt.xml
Автор(ы): Jeff Prosise
Дата: 22.02.2001

В этой статье подробно рассматриваются подразделения (apartments) в модели
COM. Автор описывает различные виды подразделений, показывает, каким образом
подразделения назначаются потокам и объектам, а также даёт ряд полезных
советов, которые позволят вам избежать ошибок при работе с подразделениями.


оригинал тут

http://codeguru.earthweb.com/activex/COMApartments1.html
http://codeguru.earthweb.com/activex/COMApartments2.html
\/\/i||i
Re: Как запустить COM в другом потоке?
От: The Lex Украина  
Дата: 18.10.01 17:00
Оценка:
Здравствуйте Константин, Вы писали:

Много то как, сразу и не разберешь... :)

К>Сделал простейший COM-Server.

Молодец! Так держать! :)

К>В клиентском MFC-приложении запускаю поток — класс, производный от CWinThread. В его InitInstance делаю СoInitialize и пытаюсь получить доступ к своему Server-у, используя SmartPointer-ы. В ответ — сообщение об ошибке (Invalid pointer = 0).

Совет номер 1: делай CoInitialize(...) в InitInstance(...) приложения и не забывай делать CoUninitialize(...) в ExitInstance(...) — все пока работает.

К>При отладке — сообщение что-то типа "MYServer.dll relocated due to collision with Some.dll..."

Совет номер 2: не обращай мнимания на это сообщение: у меня COM-DLL-ек штук по пять-шесть грузится и на каждую он пишет подобные страшные вещи. Что означают — не знаю — это, вон, к гуру. Знаю что на это можно не обращать внимания.

К>Если все делать в рамках главного потока программы — все ОК (сообщение о collision). Но мне нужно иметь доступ к COM внутри другого потока.

И имей доступ к своему COM внутри другого потока: CoCreateInstance(...) (или как там они на "хитрых поинтерах" создаются) — и вперед!!!
Голь на выдумку хитра, однако...
Re[3]: Как запустить COM в другом потоке?
От: The Lex Украина  
Дата: 19.10.01 05:27
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

AF>... (см. выше)


Спасибо! Надо будет это применить. Люблю хорошие ответы на хорошие вопросы — это когда все друг-друга понимают... :)
Голь на выдумку хитра, однако...
Re: Как запустить COM... - Спасибо, разобрался.
От: Константин  
Дата: 19.10.01 10:17
Оценка:
Спасибо за сообщения
Благодаря "Пониманию подразделений COM" вроде бы разобрался.
В InitInstance потока вызываю СoInitialize() (согласно статье, каждый поток, использующий COM, должен вызывать CoInitialize[Ex]() — по-видимоиу, чтобы поместиться в к-л Apartment-e ).
Кроме того, добавил в реестр ThreadingModel=Apartment (это наверное, чтобы поместить СOM объект в тот же Apartment, где находится и создавший объект поток — в моем случае). Проверил отладчиком — вроде бы все работает.
Re[2]: Как запустить COM в другом потоке?
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.10.01 19:48
Оценка:
Здравствуйте The Lex, Вы писали:

TL>И имей доступ к своему COM внутри другого потока: CoCreateInstance(...) (или как там они на "хитрых поинтерах" создаются) — и вперед!!!


Чтобы иметь доступ к апартаментному компоненту расположенному в другом апартаменте (потоке для Апартмент-компонетов) нужно или получить указатель на объект через метод отмаршаленого COM-объекта, или делать ручной маршалинг (в стрим и обратно), или использовать GIT. Иначе кроме глюков ничего не получить.

Альтернативу можно получить используя FTM.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Как запустить COM... - Спасибо, разобрался.
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.10.01 19:57
Оценка:
Здравствуйте Константин, Вы писали:

К>Спасибо за сообщения

К>Благодаря "Пониманию подразделений COM" вроде бы разобрался.
К>В InitInstance потока вызываю СoInitialize() (согласно статье, каждый поток, использующий COM, должен вызывать CoInitialize[Ex]() — по-видимоиу, чтобы поместиться в к-л Apartment-e ).

CoInitialize() и CoInitializeEx() как раз и создают (инициализируют апартамент).


К>Кроме того, добавил в реестр ThreadingModel=Apartment


А на чем написан сам объект? Большинство библиотек избавляют от прописывания данных в реестре.

К>(это наверное, чтобы поместить СOM объект в тот же Apartment, где находится и создавший объект поток — в моем случае). Проверил отладчиком — вроде бы все работает.


Нет это для того, чтобы COM знал, что этот объект должен загружаться в STA. Например, если создать такой объект из MTA-потока, то объект будет создан в новом апартаменте, а если в уже существующем STA (как это ты делал в самом начале), то объект будет создан в том же апартаменте. Во втором случае маршалинга не будет. Не будет и возможности параллельно обращаться к объектам созданным в одном STA.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Как запустить COM... - Спасибо, разобрался.
От: Константин  
Дата: 22.10.01 06:02
Оценка:
Здравствуйте VladD2, Спасибо за ответы. Вы писали:


К>>Кроме того, добавил в реестр ThreadingModel=Apartment

VD>А на чем написан сам объект? Большинство библиотек избавляют от прописывания данных в реестре.

Вообще то к своему стыду, на голом так сказать С++.
Re[4]: Как запустить COM... - Спасибо, разобрался.
От: Alex Fedotov США  
Дата: 22.10.01 06:45
Оценка:
Здравствуйте Константин, Вы писали:

VD>>А на чем написан сам объект? Большинство библиотек избавляют от прописывания данных в реестре.


К>Вообще то к своему стыду, на голом так сказать С++.


Не огорчайся сильно, это со временем проходит :)
-- Alex Fedotov
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.