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

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

Thread u Com [WinXP]


kblc ©   (2005-11-28 13:00:00) 

Уважаемые мастера, почему у меня не работает слудующий код:
У меня есть COM сервере который имеет интерфейс IIntf1;
Почему же не работает след:

procedure proc1;
var
 i1L IIntf1;
begin
 CoInitialize(nil);
 try
   IIntf:=CreateComObject(ProgIDToClassID('srv.serv')) as IINtf1;
   // exception: Iterface no supported;
 finally
   CoUninitialize;
 end;
end;

begin
 CreateThread(...., @proc1, ....);
 .....
end;


Если тоже самое ( IIntf := CreateComObject( ProgIDToClassID('srv.serv')) as IINtf1;) сделать в форме, то всё прекрасно работает?

Будьте добры - подскажите...


Набережных С.   (2005-11-29 12:22:00) [1]

Прошу прощения за дубль. Даже не понял, как оно получилось:(


Набережных С.   (2005-11-29 12:16:00) [2]

Для того, чтобы интерфейсную ссылку можно было передать через границу апартаментов существует механизм маршалинга. Для каждого интерфейса в системе регистрируются размещенные в ДЛЛ специальные объекты, называемые Proxy and Stub. Если интерфейс использует в методах только Ole-совместимые типы, для него есть библиотека типов и он соответствующим образом зарегистрирован, то в качестве Proxy/Stub для него может быть использован универсальный маршалер из OleAut32. В противном случае это должны быть специально для него написанные объекты. Прокси создается подсистемой СОМ в апартаменте клиента, и именно его интерфейс получает клиент. Стаб размещается в апартаменте самого объекта и содержит ссылку на соответствующий интерфейс этого объекта.

Когда клиент вызывает метод объекта, реально он вызывает метод прокси. Внутри него прокси упаковывает параметры метода в пакет и отправляет этот пакет по каналу связи в апартамент объекта. Там пакет поступает к парному стабу. Тот распаковывает параметры и производит вызов собственно метода объекта, после этого упаковывает ответные данные и отправляет их прокси, а та уже передает их клиенту.

Соответственно, если при попытке установить связь СОМ не находит для интерфейса Proxy/Stub, она извещает о невозможности установления связи возвратом кода E_NOINTERFACE. И я не помню, чтобы СОМ возвращала такую ошибку еще в каких-то случаях, кроме мной указанных в [11].

Повторю, все это имеет место только тогда, когда COM-объект и его клиент находятся в разных апартаментах. В одном апартаменте вся работа идет напрямую.

Более развернуто это все описано в MSDN. Или, например, у Дона Бокса, в книге "Сущность технологии COM"


kblc   (2005-11-29 12:04:00) [3]

2 Digitman: kblc ©   (28.11.05 16:40) [8]


Набережных С.   (2005-11-29 11:51:00) [4]

Для того, чтобы интерфейсную ссылку можно было передать через границу апартаментов существует механизм маршалинга. Для каждого интерфейса в системе регистрируются размещенные в ДЛЛ специальные объекты, называемые Proxy and Stub. Если интерфейс использует в методах только Ole-совместимые типы, для него есть библиотека типов и он соответствующим образом зарегистрирован, то в качестве Proxy/Stub для него может быть использован универсальный маршалер из OleAut32. В противном случае это должны быть специально для него написанные объекты. Прокси создается подсистемой СОМ в апартаменте клиента, и именно его интерфейс получает клиент. Стаб размещается в апартаменте самого объекта и содержит ссылку на соответствующий интерфейс этого объекта.

Когда клиент вызывает метод объекта, реально он вызывает метод прокси. Внутри него прокси упаковывает параметры метода в пакет и отправляет этот пакет по каналу связи в апартамент объекта. Там пакет поступает к парному стабу. Тот распаковывает параметры и производит вызов собственно метода объекта, после этого упаковывает ответные данные и отправляет их прокси, а та уже передает их клиенту.

Соответственно, если при попытке установить связь СОМ не находит для интерфейса Proxy/Stub, она извещает о невозможности установления связи возвратом кода E_NOINTERFACE. И я не помню, чтобы СОМ возвращала такую ошибку еще в каких-то случаях, кроме мной указанных в [11].

Повторю, все это имеет место только тогда, когда COM-объект и его клиент находятся в разных апартаментах. В одном апартаменте вся работа идет напрямую.

Более развернуто это все описано в MSDN. Или, например, у Дона Бокса, в книге "Сущность технологии COM"


Digitman   (2005-11-29 11:29:00) [5]

а трэдинг-модель какая у фабрики ?


kblc   (2005-11-29 10:43:00) [6]

var Unk: IUnknown;
   Intf: IIntf1;
..
  Unk:=CreateComObject(ProgIDToClassID('srv.serv'));
 Intf:= Unk as IIntf1; // <- исключение возбуждается именно здесь ?
..

В том то и дело что ИМЕННО ТАМ!!!!


Digitman   (2005-11-29 08:14:00) [7]

т.е. ты утверждаешь что

var Unk: IUnknown;
    Intf: IIntf1;
..
  Intf:=CreateComObject(ProgIDToClassID('srv.serv'));
  Intf:= Unk as IIntf1; // <- исключение возбуждается именно здесь ?
..


kblc   (2005-11-29 07:29:00) [8]

Digitman, узнал это пользуясь отладчиком. хм.. есть другие способы?


kblc   (2005-11-29 07:28:00) [9]

Набережных С., можно поподробнее на счёт "интерфейс невозможно маршалировать в апартамент потока из-за отсутствия в системе Proxy/Stub для него.", потому как интерфейс действительно поддерживается.


Набережных С.   (2005-11-28 20:44:00) [10]

Собственно, эта ошибка возвращается в двух случаях - либо у объекта действительно нет запрошенного интерфейса, либо этот интерфейс невозможно маршалировать в апартамент потока из-за отсутствия в системе Proxy/Stub для него.


Digitman   (2005-11-28 17:15:00) [11]


> вот на этой строчке появляется exception "Interface not
> supported".


как узнал ?


Leonid Troyanovsky   (2005-11-28 17:01:00) [12]


> kblc ©   (28.11.05 16:40) [8]

> BeginThread не помогло... :(


Чему не помогло?

--
Regards, LVT.


kblc   (2005-11-28 16:40:00) [13]


var
 GUID: TGIUD;
begin
CoInitialize(nil);
try
 GUID:=ProgIDToClassID('srv.serv');
 IIntf:=CreateComObject(GUID) as IINtf1;  // <- вот на этой строчке появляется exception "Interface not supported".
finally
 CoUninitialize;
end;

а если использовать объект оле, например
cVariant:=CreateOleObject('Word.Application'); cVariant.Open(...);, то всё работает.
Насколько я понимаю проблема в самой реализации интерфейса. У меня при инициализации фабрики след. параметры:
ThreadingModel = tmApartment;
ClassInstance = ciSingleInstance;


П.С.
BeginThreadне помогло... :(


Digitman   (2005-11-28 16:00:00) [14]


> имел ввиду повторить код
> в любом обработчике формы


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

поясни В КОДЕ, на основании чего ты сделал умозаключение насчет Iterface no supported..


kblc   (2005-11-28 15:35:00) [15]

Leonid Troyanovsky ©   (28.11.05 15:26) [4]
Прошу прощения за код - писал ручками, торопился.

Мануал читаю.. пока не до конца въехал...


kblc   (2005-11-28 15:30:00) [16]

я имел ввиду повторить код
 try
  IIntf:=CreateComObject(ProgIDToClassID('srv.serv')) as IINtf1;
  // exception: Iterface no supported;
finally
  CoUninitialize;
end;

в любом обработчике формы. т.е. я хочу сказать что код полностью работоспособный, но в потоку выполняться не хочет. вот. как с этим бороться?


Leonid Troyanovsky   (2005-11-28 15:26:00) [17]


> kblc ©   (28.11.05 15:13) [2]
> По моему я дописал:

>   // exception: Iterface no supported;


Вот, когда, например, я изображаю из себя компилятор,
то также игнорирую комментарии.

Т.е., место возникновения ошибки можно было бы обозначить
поясней (тем более, что приведенный код не компилировался,
см., например, var i1L IIntf1).

Ну, а вообще-то, для начала RTFM: Delphi help: BeginThread.

--
Regards, LVT.


Digitman   (2005-11-28 15:23:00) [18]

тогда рассказывай, что такое "сделать в форме" ..

ибо "форма" и "thread" далеки друг от друга как "в огороде бузина" от "в Киеве дядька"


kblc   (2005-11-28 15:13:00) [19]

По моему я дописал:
 try
  IIntf:=CreateComObject(ProgIDToClassID('srv.serv')) as IINtf1;
  // exception: Iterface no supported;
finally
  CoUninitialize;
end;


Digitman   (2005-11-28 13:15:00) [20]


> Почему же не работает след


неужели так и говорит, мол,  "не работаю" ?


Наверх

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