Народ. У меня такой трабл:
есть два процесса:
в первом есть один COM объект A
во втором два COM объекта B , C
Объекты B и C исполняются в разных потоках.
Объект B получает указатель на объект A.
Я передаю его в объект C, после чего пытаюсь запросить нужный мне интерфейс и вызвать метод. Мне выдают ошибку связанную с маршалингом. Как это обойти?
Здравствуйте, <Аноним>, Вы писали:
А>Народ. У меня такой трабл: А>есть два процесса: А>в первом есть один COM объект A А>во втором два COM объекта B , C
А>Объекты B и C исполняются в разных потоках. А>Объект B получает указатель на объект A. А>Я передаю его в объект C, после чего пытаюсь запросить нужный мне интерфейс и вызвать метод. Мне выдают ошибку связанную с маршалингом. Как это обойти?
Объект B получает на самом деле прокси интерфейса объекта A. Пытаясь вызвать метод из другого потока прокся возврящяет ошибку.
Возможно 2 варианта
1. Использовать неявный маршалинг, т. е. передать интерфейс объекту C их объекта B через метод, но в этом случае объект B должен держать отмаршалированную ссылку на объект С.
2. Использовать GIT
3. Использовать апи-функции CoMarshalInterface, CoUnmarshalInterface
NB! Поскольку ты будешь маршалить прокси нужно учесть 2 вещи
1. Апартамент в котором живет объект B должен жить до тех пор пока ты не отпустишь ссылку из объекта C на объект A
2. Если захочешь несколько раз размаршаливать, то нельзя использовать CoMarshalInterface с параметром MSHLFLAGS_TABLESTRONG он не умеет маршалить прокси — придеться воспользоватьмя GIT-ом
Невозможное мы сделаем сегодня — чудо займет немного больше времени. /Аноним/
Здравствуйте, UnrealAlex, Вы писали:
UA>Здравствуйте, <Аноним>, Вы писали:
А>>Народ. У меня такой трабл: А>>есть два процесса: А>>в первом есть один COM объект A А>>во втором два COM объекта B , C
А>>Объекты B и C исполняются в разных потоках. А>>Объект B получает указатель на объект A. А>>Я передаю его в объект C, после чего пытаюсь запросить нужный мне интерфейс и вызвать метод. Мне выдают ошибку связанную с маршалингом. Как это обойти? UA>Объект B получает на самом деле прокси интерфейса объекта A. Пытаясь вызвать метод из другого потока прокся возврящяет ошибку. UA>Возможно 2 варианта UA>1. Использовать неявный маршалинг, т. е. передать интерфейс объекту C их объекта B через метод, но в этом случае объект B должен держать отмаршалированную ссылку на объект С. UA>2. Использовать GIT UA>3. Использовать апи-функции CoMarshalInterface, CoUnmarshalInterface
UA>NB! Поскольку ты будешь маршалить прокси нужно учесть 2 вещи UA>1. Апартамент в котором живет объект B должен жить до тех пор пока ты не отпустишь ссылку из объекта C на объект A UA>2. Если захочешь несколько раз размаршаливать, то нельзя использовать CoMarshalInterface с параметром MSHLFLAGS_TABLESTRONG он не умеет маршалить прокси — придеться воспользоватьмя GIT-ом
Функции объекта A требуются в обработчике асинхронного вызова в объекте B.
Асинхронный вызов проходит очень часто. Если не сложно, что мне выбрать конкретнее?
Здравствуйте, x2004, Вы писали:
X>Функции объекта A требуются в обработчике асинхронного вызова в объекте B. X>Асинхронный вызов проходит очень часто. Если не сложно, что мне выбрать конкретнее?
Немного не понял. Изначально стояла проблема с объектом С! Что еть в твоем понимании асинхронный вызов? PostMessage? APC?
Можешь описать проблему более подробно.
Невозможное мы сделаем сегодня — чудо займет немного больше времени. /Аноним/
Здравствуйте, UnrealAlex, Вы писали:
UA>Здравствуйте, x2004, Вы писали:
X>>Функции объекта A требуются в обработчике асинхронного вызова в объекте B. X>>Асинхронный вызов проходит очень часто. Если не сложно, что мне выбрать конкретнее? UA>Немного не понял. Изначально стояла проблема с объектом С! Что еть в твоем понимании асинхронный вызов? PostMessage? APC? UA>Можешь описать проблему более подробно.
Честно говоря все равно где... в B или в C
Объекты B и C содержат в себе функцию, которая осуществляет асинхронный вызов APC
QueueUserAPC(ApcFunc,hThread,dwParam);
В ApcFunc требуется вызвать методы A, Сама ApcFunc исполняется в ином потоке, чем родительский класс — hThread.
Интерфейс A передается в поток родительского класса (B или C). Но когда пытаешься пользоваться ею в потоке hThread — абзац... Ошибка маршалинга. QueueUserAPC я зову достаточно часто и вызов методов А (и видимо маршалинг демаршалинг) мне нужно производить очень часто...
Здравствуйте, x2004, Вы писали:
UA>>Здравствуйте, x2004, Вы писали: X>Честно говоря все равно где... в B или в C X>Объекты B и C содержат в себе функцию, которая осуществляет асинхронный вызов APC
X>QueueUserAPC(ApcFunc,hThread,dwParam);
X>В ApcFunc требуется вызвать методы A, Сама ApcFunc исполняется в ином потоке, чем родительский класс — hThread. X>Интерфейс A передается в поток родительского класса (B или C). Но когда пытаешься пользоваться ею в потоке hThread — абзац... Ошибка маршалинга. QueueUserAPC я зову достаточно часто и вызов методов А (и видимо маршалинг демаршалинг) мне нужно производить очень часто...
Тогда используй GIT (проверка ошибок опущена для наглядности)
1. Получаешь интерфейс на объект A
2. Кладешь его в GIT
::CoInitializeEx(0, COINIT_MULTITHREADED); // если в этом потоке не было вызвано ранее
CComPtr<IA> pIA;
CComPtr<IGlobalInterfaceTable> ptrGIT;
pIA.CoCreateInstance(CLSID_A);
ptrGIT.CoCreateInstance(CLSID_StdGlobalInterfaceTable);
ptrGIT->GetInterfaceFromGlobal(dwCookie, __uuidof(pIA), reinterpret_cast<void**>(&pIA));
pIA = NULL;
::CoUninitialize(); // если вызвал в начале ::CoInitializeEx(0, COINIT_MULTITHREADED)
З.Ы.
1. не забудь вызвать RevokeInterfaceFromGlobal
2. как я уже говорил — раз ты маршалишь прокси надо обеспечить жизнь апартамента, в котором она была замаршалена до вызова RevokeInterfaceFromGlobal
3. Не забудь определить макрос _WIN32_DCOM перед включением objbase.h
Невозможное мы сделаем сегодня — чудо займет немного больше времени. /Аноним/