Следющая ситуация:
Имееться 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 )))
Здравствуйте, 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>>
Здравствуйте, Константин Л., Вы писали:
КЛ>Здравствуйте, 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 пересел и еще не до конца врубаюсь в систему маршалингов. Зарание спасибо за ответ, надеюсь на его подробность(желательно с кодом или ссылками по теме)=)
спасибо за ответ! дело действительно в типе апартмента, нужен STA. Стоило добавить строчку к коду и все заработало:
m_Thread = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this, &MyThread::ThreadMethod));
m_Thread->ApartmentState = System::Threading::ApartmentState::STA;
m_Thread->Start();