2014-10-15 4 views
0

Я разработал проект C++ ATL с простым COM-объектом, который будет использоваться в VB6. Я выбрал опции, позволяющие слить прокси/заглушку. Проект использует модель с однопоточной квартирой, двойной интерфейс и поддерживает точки подключения.Обработка аварийных сообщений диспетчеризации COM VB6 скомпилированный код

Я добавил методы к интерфейсу и dispinterface и реализовал методы «огонь», запустив мастер «Установить точку подключения» (aka Add Connection Point). Я сделал тестовые приложения в VB6 для использования COM-объекта. Одно приложение - это именованный сервер каналов, а другой - именованный клиент канала.

В этих приложениях я добавил ссылку на объект и затушевал глобально на форме. На сервере я дополнительно объявил его «WithEvents».
VB6 видит объект WithEvents и позволяет мне добавить код обработчика событий.

Когда я запускаю приложения в VB6, нажав кнопку воспроизведения (через VB6.exe), мой сервер запускается и клиент подключается. Мой сервер запускает событие, и обработчик события vb6 обрабатывает его. Это здорово и просто то, что я хотел.

Когда я создаю исполняемые файлы VB6 приложений и запускаю их, происходит такая же последовательность событий, что и сервер. При отладке сбой кода - это метод IDispatch :: Invoke кода «Fire». Мой сервер, после запуска, запускается в отдельном потоке, чтобы принять соединение с каналом. В этом отдельном потоке выдается событие пожара.

Возможно, я нарушаю модель STA (я не знаю), но я следовал инструкциям в моей книге программирования об использовании событий для длительных задач. Примеры кода всегда показывают, что поток порожден, и из этого потока вызывается метод пожара. Любое понимание было бы весьма благодарным.

+0

Вам нужно будет написать _lot_ более подробную информацию о любом случае полезного ответа. – xxbbcc

+4

Да, вы нарушаете STA. Это * приведет к краху приложения VB6. Вы должны маршевать указатель интерфейса в своем потоке, чтобы событие запускалось в потоке STA, который создавал среда выполнения VB6. Обычно IGlobalInterfaceTable - это более простой способ сделать это. –

+0

Спасибо! Я исследовал это, и он точно описывает мой прецедент. Ранее я упоминал в другом посте, что я решил проблему, изменив модель потоковой передачи на «Свободный», но мне это нравится лучше. Я не привык использовать модель «Free» для потоковой передачи. –

ответ

0

Упоминание об использовании интерфейса IGlobalInterfaceTable для маршалинга интерфейса указателя на другую квартиру описывает именно мой прецедент. Я попробую этот метод и подтвержу ответ.

+0

Вы на самом деле похоронили проблему - VB6 не может получать события ни на чем, кроме STA, на котором был создан объект VB6. – wqw

+0

Спасибо. Я вернулся к коду и сменил его с бесплатной резьбовой назад на квартиру; например исходя из CComSingleThreadModel и изменения модели реестра для квартиры. Я работаю над реализацией предлагаемого решения. –

+0

К сожалению, я не мог заставить альтернативное решение работать. Я успешно смог зарегистрировать и отменить интерфейс, однако при использовании cookie он никогда не вернет мне интерфейс. Это было очень неприятно. Кроме того, я думаю, что мой метод работает; Я не упомянул одну деталь. Событие отправки запускается из объекта-указателя, который был создан в том же потоке, что и объект COM. Я просто делаю это из другого потока и блокируюсь во всем мире с помощью Mutex. –

Смежные вопросы