COM && Thread
От: XProgrammer  
Дата: 12.10.06 07:52
Оценка:
Следющая ситуация:
Имееться COM-сервер(написан на FMC)и клиент(пишется на Win Form App Managed Code), который через заданные интервалы времени поднимает должен создавать N штук интерфейсов и вызвать их с разными параметрами...
Вся проблема в том, что как только я перемещаю код поднятия интерфейса внутрь созданного потока(System::Threading::Thread), так сразу при вызове метода(HRESULT RunOptionsDlg ([In, Out, MarshalAs(UnmanagedType::LPWStr)]System::String^ Str) интерфейса возникает ошибка:
An unhandled exception of type 'System.InvalidCastException' occurred in Client.exe
Additional information: Unable to cast COM object of type 'System.__ComObject' to interface type 'Client.IWork'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{055362DA-9A72-4585-8C05-D9D71D450228}' failed due to the following error: Интерфейс не поддерживается (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

ЗЫ: Подозреваю что тут дело в безопасных потоках...Если можно, отвечайте подробнее — я только что пересел с MFC под .NET )))
Re: COM && Thread
От: Константин Л. Франция  
Дата: 12.10.06 08:37
Оценка:
Здравствуйте, XProgrammer, Вы писали:

XP>Следющая ситуация:

XP>Имееться COM-сервер(написан на FMC)и клиент(пишется на Win Form App Managed Code), который через заданные интервалы времени поднимает должен создавать N штук интерфейсов и вызвать их с разными параметрами...
XP>Вся проблема в том, что как только я перемещаю код поднятия интерфейса внутрь созданного потока(System::Threading::Thread), так сразу при вызове метода(HRESULT RunOptionsDlg ([In, Out, MarshalAs(UnmanagedType::LPWStr)]System::String^ Str) интерфейса возникает ошибка:
XP>An unhandled exception of type 'System.InvalidCastException' occurred in Client.exe
XP>Additional information: Unable to cast COM object of type 'System.__ComObject' to interface type 'Client.IWork'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{055362DA-9A72-4585-8C05-D9D71D450228}' failed due to the following error: Интерфейс не поддерживается (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

XP>ЗЫ: Подозреваю что тут дело в безопасных потоках...Если можно, отвечайте подробнее — я только что пересел с MFC под .NET )))


COM объекты STA'шные?
1. Поставь методу нового потока STAThreadAttribute.
2. надо замаршалить интерфейсы в этот новый поток
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: COM && Thread
От: XProgrammer  
Дата: 12.10.06 16:50
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>Здравствуйте, XProgrammer, Вы писали:


XP>>Следющая ситуация:

XP>>Имееться COM-сервер(написан на FMC)и клиент(пишется на Win Form App Managed Code), который через заданные интервалы времени поднимает должен создавать N штук интерфейсов и вызвать их с разными параметрами...
XP>>Вся проблема в том, что как только я перемещаю код поднятия интерфейса внутрь созданного потока(System::Threading::Thread), так сразу при вызове метода(HRESULT RunOptionsDlg ([In, Out, MarshalAs(UnmanagedType::LPWStr)]System::String^ Str) интерфейса возникает ошибка:
XP>>An unhandled exception of type 'System.InvalidCastException' occurred in Client.exe
XP>>Additional information: Unable to cast COM object of type 'System.__ComObject' to interface type 'Client.IWork'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{055362DA-9A72-4585-8C05-D9D71D450228}' failed due to the following error: Интерфейс не поддерживается (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

XP>>ЗЫ: Подозреваю что тут дело в безопасных потоках...Если можно, отвечайте подробнее — я только что пересел с MFC под .NET )))


КЛ>COM объекты STA'шные?

КЛ>1. Поставь методу нового потока STAThreadAttribute.
КЛ>2. надо замаршалить интерфейсы в этот новый поток


COMы обычные, те STA`ные...
Насчет STAThreadAttribute поподобнее пожалуста, объясни как конченому нубу...

интерфес объявлен так(я его упростил как можно):
[ComImport]
[InterfaceType(ComInterfaceType::InterfaceIsIUnknown)]
[Guid("055362DA-9A72-4585-8C05-D9D71D450228")]

interface class IWork
{
HRESULT RunOptionsDlg ([In, Out, MarshalAs(UnmanagedType::LPWStr)]System::String^ Str);
};

а вот метод самой нити:

void MyThread::ThreadMethod(void) {
using namespace System;
System::Type^ temp;
IWork^ Work;
temp = Type::GetTypeFromProgID(L"MAGICS.BASE");
Work = static_cast<IWork^>(Activator::CreateInstance(temp));
System::String^ Str = gcnew System::String(L"12345");
HRESULT re = Work->RunOptionsDlg(Str);
}
а вот как я его создаю:
m_Thread = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this, &MyThread::ThreadMethod));

ЗЫ: Повторяю я только что с MFC пересел и еще не до конца врубаюсь в систему маршалингов. Зарание спасибо за ответ, надеюсь на его подробность(желательно с кодом или ссылками по теме)=)
Re[2]: COM && Thread
От: XProgrammer  
Дата: 12.10.06 17:10
Оценка:
спасибо за ответ! дело действительно в типе апартмента, нужен STA. Стоило добавить строчку к коду и все заработало:
m_Thread = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this, &MyThread::ThreadMethod));
m_Thread->ApartmentState = System::Threading::ApartmentState::STA;
m_Thread->Start();
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.