none
Marshal.GetObjectForIUnknown returns E_NOINTERFACE, RRS feed

  • Question

  • It has been a 3rd day since I've been working on the ollowing piece of code but without any luck. Tried google again no Luck.
    Here is that little piece that have been driving me to the hell.

    object Result=null;

            IntPtr myObject = IntPtr.Zero;

            IntPtr TestInterfacePtr;

            Guid InterfaceId = typeof(IMyInterface).GUID;

     

           

     

            //This call succeeds with the expected result

           int val= NativeMethods.CreateObject(ref classId, ref InterfaceId, out myObject);

     

            // Just to test if My object is attached with the desired Interface

            //This call even succeeds with the expected result

           int test=Marshal.QueryInterface(myObject,ref InterfaceId, out TestInterfacePtr);

     

              // This is creating nightmare

           Result=Marshal.GetObjectForIUnknown(myObject);

     

            return Result as IInArchive;


    So, can anyone please tell me what is wrong with the call
    Result=Marshal.GetObjectForIUnknown(myObject);
    When I try to execute the above statement compiler throws an exception
    No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE))

    I have no big experience to the COM programming but I guess If
    Marshal.QueryInterface() call succeeds with the expected result then the Marshal.GetObjectForIUnknown(myObject), should also return a valid object without throwing any exception.

    Thanks everyone.


    Hello all
    Thursday, August 21, 2008 11:50 AM

Answers

  • Marshal.GetObjectForIUnknown() can only work when you create a Runtime Callable Wrapper (RCW) for the COM object.  In other words, have run Tlbimp.exe.  It doesn't look like you made an RCW, you wouldn't have to monkey with CreateInstance and QueryInterface if you did.  You'd just use "new" and a cast instead.
    Hans Passant.
    Friday, August 22, 2008 1:16 AM
    Moderator
  • How COM like are these interfaces? The CLR is kind of picky and requires correct implementations if IUnknown and all the related rules (QueryInterface must be reflexive, symmetric and transitive etc). "Fake" COM implementations may get some of the details wrong.


    Mattias, C# MVP
    Monday, August 25, 2008 9:21 AM
    Moderator

All replies

  • I don't know why that happens, but why are you using these Marshal methods to begin with? A regular cast should accomplish the same thing

    return (IInArchive)myObject;

    Mattias, C# MVP
    Thursday, August 21, 2008 2:04 PM
    Moderator
  • Marshal.GetObjectForIUnknown() can only work when you create a Runtime Callable Wrapper (RCW) for the COM object.  In other words, have run Tlbimp.exe.  It doesn't look like you made an RCW, you wouldn't have to monkey with CreateInstance and QueryInterface if you did.  You'd just use "new" and a cast instead.
    Hans Passant.
    Friday, August 22, 2008 1:16 AM
    Moderator
  • Hi Mattias Sjögren,
    Direct Casting can be the best approach but I don't see any way around except marshaling, since myObject is a IntPtr and I can not simply cast a IntPtr to a IInArchive interface directly.

    @nobugz,
    Yes, I didnot create any RCW. I'll try to follow what you said and update you with the result.

    Thank you both for your time.

    Peace
    arjuns

    Hello all
    Friday, August 22, 2008 5:07 AM
  • Sorry my bad, I misread your code. So what's this NativeMethods.CreateObject method? Can this object only be created with that function, and not via CoCreateInstance/new like most COM objects? If you have to create it this way, can you not change the declaration of CreateObject so that it returns a IInArchive reference directly instead of an IntPtr?

    Another thing that can cause unexpected E_NOINTERFACE errors is incorrect apartment settings. If you're running this code on your main thread, do you have the [STAThread] attribute on your Main method?



    Mattias, C# MVP
    Friday, August 22, 2008 7:31 AM
    Moderator
  • Hi,
    I have no other choices except using CreateObject the only available export for the dll. The dll itself is not a perfect COM dll , what it contains is Com like interface all over. I have once found similar issues(not exactly like mine) while fiddling with the google, that also talked about Thread Apartment but I am not sure if this is what eating my head.
    I even have attached my process entry point with [STAThread]. But i want to know, if the object I mean IInArcive is created in different thread in the dll would cause the same problem ?




    Hello all
    Friday, August 22, 2008 1:43 PM
  • How COM like are these interfaces? The CLR is kind of picky and requires correct implementations if IUnknown and all the related rules (QueryInterface must be reflexive, symmetric and transitive etc). "Fake" COM implementations may get some of the details wrong.


    Mattias, C# MVP
    Monday, August 25, 2008 9:21 AM
    Moderator