Home All Groups Group Topic Archive Search About

Casting problem : COMImport interfaces in different assemblies

Author
10 Oct 2006 5:04 AM
Bob S
A class in assembly A implements a COM interface as follows :

[ComImport, Guid("CEF04FDF-FE72-11d2-87A5-00C04F6837CF"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IMyInterface
{
[PreserveSig]
int MyMethod();
}

class MyClass : IMyInterface
{
int MyMethod()
{
....
}
}

This interface is exposed to the unmanaged world via COM Interop.

Now, assembly B also defines IMyInterface and gets this interface from the
unmanaged world as follows :

IntPtr unk = GetMyInterface(); // Gets IMyInterface from unmanaged world
object obj = Marshal.GetObjectFromIUnkown(unk); // its really the class
MyClass from assembly A above
IMyInterface myIntf = obj as IMyInterface; // this cast does not work and
returns null becuase of separate declarations of IMyInterface in the two
assemblies !

How to get this scenario to work? One would think that .Net would recognize
that both the interfaces are the same ( based on the ComImport and Guid
attributes) and allow the cast, but it doesnt allow the cast.

It is not possible for me to use a shared assembly and put the declaration
of IMyInterface in that assembly.

So how can I solve this problem?

Thanks
Bob

Author
10 Oct 2006 6:05 AM
Dr. Jochen Manns
As far as I understand .NET always detects in this scenario that you are
talking from .NET to .NET. So the COM InterOp is removed
(Marshal.IsComObjects reports False, Marshal.ReleaseComObject will fail -
this was very surprising in our app where the one component first was really
COM / C++ and then ported to .NET: Marshal.ReleaseComObjects throws an
exception from this day on) and in the pure .NET world you are not able to
cast an instance to a .NET interface which it does not implement.

By the way: .NET in this case is not interested in the interface attributes
at all.

Jochen

Show quote
"Bob S" <staheli.***@gmail.com> wrote in message
news:O1P%23fmC7GHA.4644@TK2MSFTNGP04.phx.gbl...
>A class in assembly A implements a COM interface as follows :
>
> [ComImport, Guid("CEF04FDF-FE72-11d2-87A5-00C04F6837CF"),
> InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
> internal interface IMyInterface
> {
> [PreserveSig]
> int MyMethod();
> }
>
> class MyClass : IMyInterface
> {
> int MyMethod()
> {
> ...
> }
> }
>
> This interface is exposed to the unmanaged world via COM Interop.
>
> Now, assembly B also defines IMyInterface and gets this interface from the
> unmanaged world as follows :
>
> IntPtr unk = GetMyInterface(); // Gets IMyInterface from unmanaged world
> object obj = Marshal.GetObjectFromIUnkown(unk); // its really the class
> MyClass from assembly A above
> IMyInterface myIntf = obj as IMyInterface; // this cast does not work and
> returns null becuase of separate declarations of IMyInterface in the two
> assemblies !
>
> How to get this scenario to work? One would think that .Net would
> recognize
> that both the interfaces are the same ( based on the ComImport and Guid
> attributes) and allow the cast, but it doesnt allow the cast.
>
> It is not possible for me to use a shared assembly and put the declaration
> of IMyInterface in that assembly.
>
> So how can I solve this problem?
>
> Thanks
> Bob
>
>
>
Author
10 Oct 2006 6:14 AM
Jon Skeet [C# MVP]
Bob S <staheli.***@gmail.com> wrote:

<snip>

> How to get this scenario to work? One would think that .Net would recognize
> that both the interfaces are the same ( based on the ComImport and Guid
> attributes) and allow the cast, but it doesnt allow the cast.

No. They're *not* the same interface. If they're in different
assemblies, they're different types.

You need to put the interface in a single assembly.

> It is not possible for me to use a shared assembly and put the declaration
> of IMyInterface in that assembly.

Why not? Why do you need both interfaces to start with?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Author
10 Oct 2006 10:36 AM
Bob S
Is not always possible to have the interface in the shared assembly, because
one .Net assembly may expose an interface (eg COM IDataObject) to the
unmanaged world while another .Net assembly may consume the interface.
Though the underlying interface is the same, .Net will not allow the
casting. (In the case of IDataObject, this situation will not arise if you
use the Microsoft defined type IOleDataObject - however this will not be
possible for other interfaces).

Thus .Net does not support the basic tenet of COM which says that COM is a
"binary standard". It should not matter what the underlying ".Net type" of
the interface is as long as the binary contract of the interface is the
same.

I think this is a serious flaw in COM support of .Net. I would love to hear
some more views on this.

Regards
Bob



Suppose assembly A exposes a COM IDataObject to the unmanaged world and
defines

Show quote
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MPG.1f954aa35c114d9d98d534@msnews.microsoft.com...
> Bob S <staheli.***@gmail.com> wrote:
>
> <snip>
>
>> How to get this scenario to work? One would think that .Net would
>> recognize
>> that both the interfaces are the same ( based on the ComImport and Guid
>> attributes) and allow the cast, but it doesnt allow the cast.
>
> No. They're *not* the same interface. If they're in different
> assemblies, they're different types.
>
> You need to put the interface in a single assembly.
>
>> It is not possible for me to use a shared assembly and put the
>> declaration
>> of IMyInterface in that assembly.
>
> Why not? Why do you need both interfaces to start with?
>
> --
> Jon Skeet - <sk***@pobox.com>
> http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
> If replying to the group, please do not mail me too

AddThis Social Bookmark Button