1

I'm using an external native COM component in my C# .NET application.

This COM DLL doesn't have a type library, so I had to write the interop code myself, and having include/idl files I did it like TlbImp does. But the worst thing is that the object creation fails with:

Creating an instance of the COM component with CLSID {40700425-0080-11D2-851F-00C04FC21759} from the IClassFactory failed due to the following error: 80040111

The class is finally created if I use the native CoCreateInstance and specify class_id and one of the implemented interface IIDs.

As it turned out the problem lies in that the COM object's IClassFactory::CreateInstance doesn't support IID_IUnknown passed as the riid parameter, and therefore returns CLASS_E_CLASSNOTAVAILABLE (I identified it with disassembler and debugger). The component is MS SQL VDI.

Is there any way to force the .NET RCW to pass a different interface ID into the CreateInstance method rather than IID_IUnknown? I searched the net a lot, but didn't find a solution for this.

As a workaround I'm using C++/CLI now to create the object, requesting the proper interface instead of IID_IUnknown for this purpose now; but I would like to have code in C#, because C++/CLI requires me to build a different DLL for each platform.

Thanks

Bondolin
  • 2,793
  • 7
  • 34
  • 62
mistika
  • 2,363
  • 2
  • 21
  • 25
  • Failing to respond to IUnknown from CoCreateInstance() is a bug. Can you get the owners of the external library to fix it? http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx – i_am_jorf Sep 18 '11 at 19:18
  • The owners are Microsoft, and since this bug has been existed for more than 10 years and taking into account that it doesn't block the component usage I don't think the patch will be available – mistika Sep 19 '11 at 16:05

1 Answers1

2

I repro. Brr, painful. You could pinvoke 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);
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thanks a lot for your suggestion, Hans. It does the trick, and simple rapper will hide it. Though it would be nice to have something like (edit -- God, how to post a linefeed in comment? NBoth Enter and CtrlEnter presses Save button). ... something like: [DefaultInterfaceGuid("XXXX-XXX-XXX")] or so. – mistika Sep 19 '11 at 15:48