2011-09-18 68 views
0

我在我的C#.Net应用程序中使用外部原生COM组件。如何管理.Net的RCW COM对象创建参数(即请求的接口)?

这个COM DLL没有类型库,所以我不得不自己编写互操作代码,并且有像TlbImp那样的include/idl文件。 但是最糟糕的事情是,对象的创建失败:

创建具有CLSID {40700425-0080-11D2-851F-00C04FC21759}的COM组件的实例从IClassFactory的失败,原因是以下错误:80040111

如果我使用本机CoCreateInstance并指定class_id和其中一个已实现的接口iids,则该类将很好地创建。

事实证明问题在于COM对象的IClassFactory :: CreateInstance不支持IID_IUnknown作为riid参数传递,因此返回CLASS_E_CLASSNOTAVAILABLE(我用反汇编器和调试器识别它)。该组件是MS SQL VDI。

有什么办法强制.Net RCW传递不同的接口ID到CreateInstance方法而不是IID_IUnknown? 搜索了很多,但没有找到解决方案。

作为一种解决方法,我正在使用C++/CLI来请求合适的接口而不是IID_IUnknown来对象化。为此目的,但希望在C#中有代码,因为C++/CLI需要我为每个平台构建不同的DLL。

谢谢

+0

无法从CoCreateInstance()响应IUnknown是一个错误。你能否让外部图书馆的所有者修复它? http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx –

+0

所有者是微软,由于这个bug已经存在超过10年,并考虑到它不会不会阻止组件使用我不认为该补丁可用 – mistika

+0

哦,哇。棒极了。 –

回答

0

我repro。 Brr,痛苦。您可以锁定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); 
+0

谢谢你的建议,汉斯。它的伎俩,简单的说唱歌手将隐藏它。虽然有这样的东西会很好(编辑 - 上帝,如何在注释中张贴换行符?NBoth Enter和CtrlEnter按下Save按钮)。 ...类似于:[DefaultInterfaceGuid(“XXXX-XXX-XXX”)]左右。 – mistika

+0

您可以使用'引用代码。 –