ActiveX события между квартирами - PullRequest
0 голосов
/ 04 октября 2008

Среда: VS2008 (ATL), Borland Developer Studio 2006.

Привет всем. У меня возникли проблемы с событиями управления ActiveX.

Вот краткое описание архитектуры моего приложения:

Существует COM-сервер inproc, который содержит элемент управления STA ActiveX (он же элемент управления) и COM-объект MTA (он же объект).

Вот определение IDL интерфейсов управления и объектов:

[
    object,
    uuid(2338CCAF-BBAF-4E29-929B-A67285B1E772),
    dual,
    nonextensible,
    pointer_default(unique)
]
interface IObject : IDispatch{
    [id(1)] HRESULT DoWork(void);
};

[
    object,
    uuid(1A0A1DA2-E33B-4DF4-99A9-9EAEF2281E7D),
    dual,
    nonextensible,
    pointer_default(unique)
]
interface IControl : IDispatch{
};


[
    uuid(BC27FABD-2794-4F9C-B3BD-C0C0628741FA),
    version(1.0),
    helpstring("AVRep 1.0 Type Library")
]

library ActiveXLib
{
    importlib("stdole2.tlb");
    [
        uuid(4B5575A7-E0FF-49B5-AE10-0D980CF49EB3)
    ]
    dispinterface _IControlEvents
    {
        properties:
        methods:
            [id(1)] HRESULT SomeEvent([in] IObject* obj);
        };
    [
        uuid(7C44F19E-6B71-434B-96F6-E29A3C66C794),
        control
    ]
    coclass Control
    {
        [default] interface IControl;
        [default, source] dispinterface _IControlEvents;
    };
    [
        uuid(17BDFAC0-DF21-4474-BCFF-846FE0075D68)
    ]
    coclass Object
    {
        [default] interface IObject;
    };
};

Клиент - это приложение Delphi с элементом управления ActiveX в форме, которое создает объект MTA и вызывает его метод DoWork

var
  mta : IObject;
begin
  mta := CreateOleObject('ActiveXLib.Object.1') as IObject;
  mta.DoWork();
end;

Этот метод напрямую вызывает метод Fire_SomeEvent элемента управления ActiveX Coclass и передает 'this' в качестве параметра (указатель на интерфейс IObject). Delphi-код успешно получает событие, но когда он пытается получить доступ к любому методу или свойству IObject (для простоты не показан в idl), то в oleaut32.dll произошло нарушение доступа.

Одно важное замечание - я использую класс ATLCPImplMT для реализации запуска событий из разных потоков (подробнее см. http://support.microsoft.com/kb/280512). Данная реализация позволяет переключать квартиры при возникновении пожара (от квартиры MTA объекта до квартиры STA Delphi формирует квартиру). Я полагаю, что эта проблема связана с неправильным маршалингом параметров событий, поскольку при использовании стандартного класса ATLCPImpl все работает нормально.

Есть ли какие-либо ограничения для мероприятий между квартирами? Возможно, для корректной работы с объектами activex требуется какая-то особая настройка среды Delphi ...

1 Ответ

1 голос
/ 07 октября 2008

Вы обращаетесь к объектам, которые были созданы в том же потоке, что и обработчик событий, или COM-объект был создан в главном потоке? Если вы не находитесь в том же контексте потока в обработчике событий, что и поток, создавший объект, вы можете получить нарушения прав доступа при попытке доступа к COM-объекту.

Обходной путь быстрого исправления может состоять в том, чтобы отправить сообщение в основной поток из обработчика событий, и чтобы основной поток получил доступ к COM-объекту в контексте основного потока, а не непосредственно в обработчике событий COM.

Threads и COM не менее сложны, чем потоки без COM.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...