Есть приложение, которое работает в основном потоке проинициализированном через OleInitialize(NULL). (Если процесс проинициализировать через CoInitializeEx(NULL, COINIT_MULTITHREADED), то проблем не будет вообще никаких, но мне так нельзя).
В этом же процессе создается поток, проинициализированный через CoInitializeEx(NULL, COINIT_MULTITHREADED). В потоке выполняется код из dll-библиотеки.
Далее во втором потоке мне необходимо создать COM-объект (потоковая модель Both) через CoCreateInstance, реализованный в основном приложении и использующий FTM (без прокси), так как дальнейшие вызовы методов этого объекта должны выполняться во втором потоке:
class ATL_NO_VTABLE IFormSupportImpl :
public IDispatchImpl<IFormSupport, &IID_IFormSupport, &LIBID_ModSystemForms>,
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<IFormSupportImpl, &CLSID_FormSupport>
{
public:
DECLARE_REGISTRY_RESOURCEID(IDR_FORMSUPPORT)
На Win2000 все работает как часы. Но на NT4 6SP все равно создается прокси и вызовы методов COM-объекта выполняются в основном потоке. В чем может быть проблема?
----------------------------------------------------
Для обхода проблемы я попытался реализовать свой маршаллер.
FormSupportProxy реализован также в основном приложении.
После вызова MarshalInterface выполнение возвращается во второй поток в точку вызова CoCreateInstance c ошибкой "Класс не зарегистрирован". FormSupportProxy при этом не создается, в реестре зарегистрирован (потоковая модель Both; регистрировал его как LocalServer32, так и InprocServer32).
Причем, если реализацию прокси вынести в отдельную библиотеку, то прокси успешно создается!
[]
K>На Win2000 все работает как часы. Но на NT4 6SP все равно создается прокси и вызовы методов COM-объекта выполняются в основном потоке. В чем может быть проблема?
Далее во втором потоке мне необходимо создать COM-объект (потоковая модель Both) через CoCreateInstance, реализованный в основном приложении и использующий FTM (без прокси),
Вот здесь не понял.
Конкретно, где создается "Both with FTM" объект?
K>---------------------------------------------------- K>Для обхода проблемы я попытался реализовать свой маршаллер.
хъ
K>После вызова MarshalInterface выполнение возвращается во второй поток в точку вызова CoCreateInstance c ошибкой "Класс не зарегистрирован". FormSupportProxy при этом не создается, в реестре зарегистрирован (потоковая модель Both; регистрировал его как LocalServer32, так и InprocServer32).
Дык сервер-то exe что-ли?
K>Причем, если реализацию прокси вынести в отдельную библиотеку, то прокси успешно создается!
Здравствуйте, Alexey Shirshov, Вы писали:
K>>На Win2000 все работает как часы. Но на NT4 6SP все равно создается прокси и вызовы методов COM-объекта выполняются в основном потоке. В чем может быть проблема?
AS>Вот здесь не понял. AS>Конкретно, где создается "Both with FTM" объект?
Нужно создать "Both with FTM" объект во втором потоке. А сама реализация объекта должна находиться в основном exe-шнике.
K>>Причем, если реализацию прокси вынести в отдельную библиотеку, то прокси успешно создается!
AS>Тогда зачем тебе FTM?
AS>Ты привел много информации не по существу.
Просто не хотел ничего упустить.
В кратце задача такая:
Есть exe-приложение, в котором реализован некий COM-объект (FormSupport) (приложение должно быть проинициализировано через OleInitialize (STM)). Есть dll, код которой выполняется в отдельном потоке. Необходимо из второго потока через CoCreateInstance создать COM-объект (FormSupport). Методы этого объекта должны выполняться без прокси во втором потоке.
Причем все это должно работать на NT4 (на Win2000 спасает, если сделать COM-объект "Both with FTM")
[]
K>Действительно, согласен, both здесь не причем. Меня интересует поведение free-threaded маршаллера.
А чего в нем непонятного. С помощью него клиенту передается прямой указатель на интерфейс. Все подробно разжевано в MSDN и на RSDN упоминалось не раз. Можешь поискать.
А с чего ты рещил, что под NT тебе возвращается прокся?
Здравствуйте, Alexey Shirshov, Вы писали:
AS>А чего в нем непонятного. С помощью него клиенту передается прямой указатель на интерфейс. Все подробно разжевано в MSDN и на RSDN упоминалось не раз. Можешь поискать.
Как должно быть в теории я себе очень хорошо представляю. На Win2000 именно так все и работает.
AS>А с чего ты рещил, что под NT тебе возвращается прокся?
Запускал на NT и смотрел в отладчике. При вызове методов объекта из второго потока стек вызовов уходит в rpcrt4.dll, а метод выполняется уже в основном потоке.
Я этой проблемой занимаюсь уже порядочно времени. Перечитал кучу статей, но причин так и не нашел.
Будет время, могу собрать небольшой тестовый проектик на VC7.