Проблема вот в чём.
Есть COM`овская dll`ка, написанная на C++. Внутри неё в вызывается CoInitializeEx(NULL, COINIT_MULTITHREADED) — там необходимо использовать многопоточную модель.
Из скрипта Rational Robot`а я пытаюсь вызвать методы из этой dll`ки:
Dim a As Object
Set a = CreateObject("XXX.XXX")
a.SameMethod 'В этом методе вызывается CoInitializeEx(...)
Так проблема в том, что CoInitializeEx возвращает ошибку RPC_E_CHANGED_MODE — "Cannot change thread mode after it is set". Хотя при вызове тех же методов из программы, написанной на C++, всё проходит нормально.
Не сталкивался ли кто-нибудь с такой проблемой? Как из Rational Robot`а вызывать методы многопоточной dll`ки?
P.S. Если сделать dll`ку однопотоковой и вызывать CoInitialize(NULL), то он не вернёт никакой ошибки.
Re: Вызов методов COM`овской dll из Rational Robot`а
Здравствуйте, Eugene Sh, Вы писали:
ES>Из скрипта Rational Robot`а я пытаюсь вызвать методы из этой dll`ки: ES>Dim a As Object ES>Set a = CreateObject("XXX.XXX") ES>a.SameMethod 'В этом методе вызывается CoInitializeEx(...)
ES>Так проблема в том, что CoInitializeEx возвращает ошибку RPC_E_CHANGED_MODE — "Cannot change thread mode after it is set". Хотя при вызове тех же методов из программы, написанной на C++, всё проходит нормально.
ES>P.S. Если сделать dll`ку однопотоковой и вызывать CoInitialize(NULL), то он не вернёт никакой ошибки.
А где ты в dll-ле вызываешь CoInitializeEx? Это допустимо только в тобой созданных потоках.
GS
Re[2]: Вызов методов COM`овской dll из Rational Robot`а
Здравствуйте, George Seryakov, Вы писали:
GS>Здравствуйте, Eugene Sh, Вы писали:
ES>>Из скрипта Rational Robot`а я пытаюсь вызвать методы из этой dll`ки: ES>>Dim a As Object ES>>Set a = CreateObject("XXX.XXX") ES>>a.SameMethod 'В этом методе вызывается CoInitializeEx(...)
ES>>Так проблема в том, что CoInitializeEx возвращает ошибку RPC_E_CHANGED_MODE — "Cannot change thread mode after it is set". Хотя при вызове тех же методов из программы, написанной на C++, всё проходит нормально.
ES>>P.S. Если сделать dll`ку однопотоковой и вызывать CoInitialize(NULL), то он не вернёт никакой ошибки.
GS>А где ты в dll-ле вызываешь CoInitializeEx? Это допустимо только в тобой созданных потоках.
Вызываю я его в конструкторе класса.
Если вызывать CoInitialize(0), то всё нормально — он возвращает S_FALSE, т.е. уже вызвана CoInitialize для однопоточной модели.
Проблема даже не в вызове CoInitializeEx, а в том, что моя dll вызывается в однопоточной модели. Внутри неё вызывается CoCreateInstance для объекта, определённого в другой dll(многопоточной). И вот тут проблема — CoCreateInstance возвращает E_NOINTERFACE.
А при тестировании моей dll из программы, написанной на C++, всё нормально — она загружается в многопоточной модели, и дальнейший вызов CoCreateInstance проходит нормально.
Re[3]: Вызов методов COM`овской dll из Rational Robot`а
Здравствуйте, Eugene Sh, Вы писали:
ES>Проблема вот в чём. ES>Есть COM`овская dll`ка, написанная на C++. Внутри неё в вызывается CoInitializeEx(NULL, COINIT_MULTITHREADED) — там необходимо использовать многопоточную модель. ES>Из скрипта Rational Robot`а я пытаюсь вызвать методы из этой dll`ки: ES>Dim a As Object ES>Set a = CreateObject("XXX.XXX") ES>a.SameMethod 'В этом методе вызывается CoInitializeEx(...)
ES>Так проблема в том, что CoInitializeEx возвращает ошибку RPC_E_CHANGED_MODE — "Cannot change thread mode after it is set". Хотя при вызове тех же методов из программы, написанной на C++, всё проходит нормально.
ES>Не сталкивался ли кто-нибудь с такой проблемой? Как из Rational Robot`а вызывать методы многопоточной dll`ки?
ES>P.S. Если сделать dll`ку однопотоковой и вызывать CoInitialize(NULL), то он не вернёт никакой ошибки.
Разберись с потоковыми моделями COM и подразделениями. Вызов CoInitialize и CoInitializeEx в dll'ке возможен только из тобой созданного потока. В этом случае формируется новое подразделение и взаимодействие между однопоточным подразделением и подразделением с моделью свободных потоков, которое было создано в dll'ке, будет происходить с соответствующей синхронизацией и маршалингом, о чем уже позаботится COM.