Foreach терпит неудачу с маршализованным интерфейсом COM - PullRequest
2 голосов
/ 08 апреля 2009

У нас есть 32-битный COM-компонент, написанный на ATL на C ++. Когда необходимо использовать его из 64-разрядного .NET, мы создаем приложение COM +, и все работает нормально.

Недавно мы заметили странное поведение на Win2k8. COM-объект в нашем компоненте запускает событие, и мы обрабатываем его в коде .NET. Событие имеет параметр, также переданный из неуправляемого кода.

Вот частичное определение для пояснения (нотация IDL):

interface IOurCollectionInterface : IDispatch 
{
[propget, restricted, id(DISPID_NEWENUM)]]
HRESULT _NewEnum( [out, retval] IUnknown** result );
}

interface IOurObjectInterface : IDispatch 
{
[propget]
HRESULT Collection( [out, retval] IOurCollectionInterface** result );
}

Обработчику событий передается экземпляр IOurObjectInterface. Внутри мы пытаемся запустить цикл foreach ().

void onEvent( IOurObjectInterface ourObject )
{
    foreach( object element in ourObject.Collection ) {
       //do stuff
    }
}

Код падает в строке с foreach со следующим сообщением: Ошибка QI для IEnumVARIANT на неуправляемом сервере

IEnumVARIANT наверняка реализован объектом, который возвращается реализацией IOurCollectionInterface::get__NewEnum(). Приведенный выше код прекрасно работает на WinXP и Win2k3, но не на Win2k8.

В чем причина такого поведения?

Ответы [ 2 ]

0 голосов
/ 08 апреля 2009

Попробуйте запустить с системной учетной записью и проверьте события для получения дополнительной информации об ошибках.

0 голосов
/ 08 апреля 2009

Трудно быть уверенным. Но заподозрил бы проблему с сортировкой.

Вы проверили, что реализация IOurCollectionInterface._NewEnum действительно вызывается?

Какой тип COM-маршалинга вы используете? Если typelib, правильно ли зарегистрирована typelib?

Это работает, если интерфейс реализован в процессе?


Из комментария sharptooth :

Используется маршаллинг Typelib, и он регистрируется. Хуже того, этот материал работает нормально, когда вызывается из приложения WinForms на той же машине, но не работает, когда вызывается из службы NT, запускаемой под локальным пользователем.

Если приложение и служба WinForms запускаются от имени разных пользователей, самое время тщательно проверить безопасность. Начните с безопасности COM +, а затем проверьте с помощью Process Monitor проблемы с доступом к реестру / файлу (это кажется маловероятным, но всегда возможно).

...