Как управлять параметрами создания COM-объекта RCW (а именно запрашиваемого интерфейса) .Net?

Я использую внешний собственный компонент COM в моем приложении C # .Net.

В этой COM-dll нет библиотеки типов, поэтому мне пришлось самому написать код взаимодействия, и, имея файлы include / idl, я сделал это, как и TlbImp. Но хуже всего то, что создание объекта завершается ошибкой:

Создание экземпляра COM-компонента с CLSID {40700425-0080-11D2-851F-00C04FC21759} из IClassFactory не удалось из-за следующей ошибки: 80040111

Класс создается точно, если я использую собственный CoCreateInstance и указываю class_id и один из реализованных идентификаторов интерфейса.

Как оказалось, проблема заключается в том, что IClassFactory :: CreateInstance COM-объекта не поддерживает IID_IUnknown, переданный как параметр riid, и поэтому возвращает CLASS_E_CLASSNOTAVAILABLE (я идентифицировал это с помощью дизассемблера и отладчика). Компонент - MS SQL VDI.

Есть ли способ заставить .Net RCW передавать другой идентификатор интерфейса в метод CreateInstance, а не в IID_IUnknown? Много искал в сети, но не нашел решения для тысяч.

В качестве обходного пути я сейчас использую C ++ / CLI для создания объекта с запросом правильного интерфейса вместо IID_IUnknown. для этой цели сейчас, но хотелось бы иметь код на C #, потому что C ++ / CLI требует, чтобы я создавал разные DLL для каждой платформы.

Спасибо


person mistika    schedule 18.09.2011    source источник
comment
Отсутствие ответа на IUnknown из CoCreateInstance () является ошибкой. Можно ли заставить владельцев внешней библиотеки это исправить? blogs.msdn.com/b/oldnewthing/archive/ 26 марта 2004 г. / 96777.aspx   -  person i_am_jorf    schedule 18.09.2011
comment
Владельцы - Microsoft, и поскольку эта ошибка существует более 10 лет, и, учитывая, что она не блокирует использование компонентов, я не думаю, что патч будет доступен.   -  person mistika    schedule 19.09.2011


Ответы (1)


Я репро. Брр, больно. Вы можете закрепить CoCreateInstance:

[return: MarshalAs(UnmanagedType.Interface)]
[DllImport("ole32.dll", ExactSpelling=true, PreserveSig=false)]
public static extern object CoCreateInstance(ref Guid clsid, 
    [MarshalAs(UnmanagedType.Interface)] object punkOuter, int context, ref Guid iid);
person Hans Passant    schedule 18.09.2011
comment
Большое спасибо за ваше предложение, Ханс. Он делает свое дело, и простой рэпер это скроет. Хотя было бы неплохо иметь что-то вроде (отредактируйте - Боже, как разместить перевод строки в комментарии? N Как Enter, так и CtrlEnter нажимают кнопку Сохранить). ... что-то вроде: [DefaultInterfaceGuid (XXXX-XXX-XXX)] или около того. - person mistika; 19.09.2011