.override directive missing in manual COM interop...

  • Thread starter Thread starter Nathan Baulch
  • Start date Start date
N

Nathan Baulch

I am so close to getting my manual COM interop classes to load correctly!
I have very slowly tracked down the problem to missing .override directives
on the classes in the IL generated from my assembly compared to that of
TlbImp.

I don't really understand why the directives exist in the first place
actually. TlbImp seems to be marking the extern methods as overriding
methods from an interface. This doesn't make much sense to me. If I try to
replicate it in my C# source by adding the "override" modifier, I get a very
predictable "There is no suitable method for override" error.

If I dump my DLL to IL, manually add in the .override directives, everything
works.
Please tell me there is a way to do this in C# and that I don't have to make
IL changes every time I need to build my assembly!


Nathan
 
Nathan said:
I am so close to getting my manual COM interop classes to load
correctly! I have very slowly tracked down the problem to missing
.override
directives on the classes in the IL generated from my assembly
compared to that of TlbImp.

I don't really understand why the directives exist in the first place
actually. TlbImp seems to be marking the extern methods as overriding
methods from an interface. This doesn't make much sense to me. If I
try to replicate it in my C# source by adding the "override"
modifier, I get a very predictable "There is no suitable method for
override" error.
If I dump my DLL to IL, manually add in the .override directives,
everything works.
Please tell me there is a way to do this in C# and that I don't have
to make IL changes every time I need to build my assembly!


Nathan
 
Nathan said:
I am so close to getting my manual COM interop classes to load
correctly! I have very slowly tracked down the problem to missing
.override
directives on the classes in the IL generated from my assembly
compared to that of TlbImp.

I don't really understand why the directives exist in the first place
actually. TlbImp seems to be marking the extern methods as overriding
methods from an interface. This doesn't make much sense to me. If I
try to replicate it in my C# source by adding the "override"
modifier, I get a very predictable "There is no suitable method for
override" error.
If I dump my DLL to IL, manually add in the .override directives,
everything works.
Please tell me there is a way to do this in C# and that I don't have
to make IL changes every time I need to build my assembly!


Nathan
 
Allow me to elaborate with an example.
My very simple VB6 COM class called SayHello looks like this:

Public Sub HelloWorld()
MsgBox "HelloWorld"
End Sub

My custom wrapper interfaces and class in C# look like this:

[ComImport]
[TypeLibType(
TypeLibTypeFlags.FHidden |
TypeLibTypeFlags.FDual |
TypeLibTypeFlags.FNonExtensible |
TypeLibTypeFlags.FDispatchable)]
[Guid("7AF7D966-0CFF-48DB-9861-8378B35C7650")]
public interface _SayHello {
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType=MethodCodeType.Runtime)]
[DispId(0x60030000)]
void HelloWorld();
}

[ComImport]
[Guid("7AF7D966-0CFF-48DB-9861-8378B35C7650")]
[CoClass(typeof(SayHelloClass))]
public interface SayHello : _SayHello {}

[ComImport]
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
[Guid("79F049E9-5C56-4C4C-83FC-79F361FDF6E8")]
[ClassInterface(ClassInterfaceType.None)]
public class SayHelloClass : _SayHello,SayHello {
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType=MethodCodeType.Runtime)]
[DispId(0x60030000)]
public extern void HelloWorld();
}

The IL for the HelloWorld method produced by MY CODE looks like this:

..method public hidebysig newslot virtual final
instance void HelloWorld() runtime managed internalcall
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = (
01 00 00 00 03 60 00 00 )
}

The IL for the HelloWorld method produced by TLBIMP looks like this:

..method public hidebysig newslot virtual
instance void HelloWorld() runtime managed internalcall
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = (
01 00 00 00 03 60 00 00 )
.override Interop.SayHelloLib._SayHello::HelloWorld
}

Notice the missing .override directive in the IL my code has produced.
After a lot of trial and error, I have found that this is the reason I get
ExecutionEngineExceptions whenever I try to use my custom wrapper.

Does anybody know how to tell the C# compiler to include .override
directives on COM class wrappers?
 
Back
Top