I'm trying to get my head around an interop issue. I have a legacy COM
DLL that I've wrapped using TLBIMP. This DLL exposes a standard
CoClass (let's call it Widget), and in the resulting interop assembly
I see the following
.class public auto ansi import WidgetClass
extends [mscorlib]System.Object
implements IWidget,
Widget
{
} // end of class WidgetClass
.class interface public abstract auto ansi import Widget
implements IWidget
{
} // end of class Widget
.class interface public abstract auto ansi import IWidget
{
} // end of class IWidget
OK, this makes sense -- I get a managed type to represent the CoClass
itself (WidgetClass), which I can instantiate. I also get a managed
interface to represent the COM interface (IWidget), which obviously I
can't instantiate, because it's an interface.
My questions are:
1. What's the Widget interface for? And why on earth am I allowed to
instantiate it? Why isn't the compiler throwing this instantiation out
like it does for IWidget? I don't see any difference between these two
interfaces -- how does the compiler know to give Widget special
treatment to break the rules of Object Orientated Programming?
2. The COM DLL exposes another CoClass (Thing) which has a property of
type Widget:
.method public hidebysig newslot specialname abstract virtual
instance class Widget
marshal( interface)
get_Widget() runtime managed internalcall
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32)
= ( 01 00 0C 00 00 00 00 00 )
} // end of method IThing::get_Widget
However, from .NET if I try to do this:
Thing aThing;
... get aThing from somewhere ...
if (aThing != null) {
string s = aThing.Widget.WidgetStringProperty;
}
I get (randomly, it seems) either a COMException or a
NullReferenceException at the point of assignment.
The only way I can access WidgetStringProperty is to do this:
string s = ((WidgetClass) aThing.Widget).WidgetStringProperty;
or
WidgetClass wc = (WidgetClass) aThing.Widget;
string s = wc.WidgetStringProperty;
either of which is most inconvenient.
What am I missing here?
Mattias Sj?gren - 12 Apr 2004 15:06 GMT
Wayne,
>1. What's the Widget interface for? And why on earth am I allowed to
>instantiate it? Why isn't the compiler throwing this instantiation out
>like it does for IWidget? I don't see any difference between these two
>interfaces -- how does the compiler know to give Widget special
>treatment to break the rules of Object Orientated Programming?
It's basicly a compiler "hack" implemented in the C# and VB.NET
compilers. Any interface that's decorated with the CoClassAttribute
can seemingly be instantiated, and the compiler changes the
instantiated type at compile time to the class indicated by the
attribute. Other languages (such as MC++) doesn't have this feature
and requires you to type out the actual class name.
You can read more about this at
http://msdn.microsoft.com/library/en-us/cpguide/html/cpcontlbimptypeconversion.asp
Mattias

Signature
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Andrew Gilmore - 12 Apr 2004 22:35 GMT
You probably will find your answer in Adam Nathan's book ".Net and Com". It
is a very comprehensive, though huge, book.
> I'm trying to get my head around an interop issue. I have a legacy COM
> DLL that I've wrapped using TLBIMP. This DLL exposes a standard
[quoted text clipped - 66 lines]
>
> What am I missing here?