Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reference type in public field causes TypeLoadException for Com Interop #47849

Closed
BickelLukas opened this issue Feb 4, 2021 · 5 comments · Fixed by #55616
Closed

Reference type in public field causes TypeLoadException for Com Interop #47849

BickelLukas opened this issue Feb 4, 2021 · 5 comments · Fixed by #55616

Comments

@BickelLukas
Copy link

Description

I am using a VB6 Library through COM Interop.
Everything works fine until the class contains a reference type as a public field.
This causes the program to throw a System.TypeLoadException: 'The Signature is incorrect' as soon it is launched.

VB6 Code:

Public Settings As clsSettings

as soon as the class containing that line gets used within the project it crashes.

Configuration

.NET Version: 5.0.102
OS: Windows 10 19042.746
Architecture: x64 (but app is built for x86 for Com interop)

Regression?

The same library can be used from .NET Framework without a Problem.

@dotnet-issue-labeler dotnet-issue-labeler bot added area-Interop-coreclr untriaged New issue has not been triaged by the area owner labels Feb 4, 2021
@AaronRobinsonMSFT
Copy link
Member

@BickelLukas Can you provide some more details on how to reproduce this? Support for IDispatch and VB6 in .NET 5+ is much more limited than in .NET Framework. Understanding exactly what is failing will help us to determine if this is an area that is intentionally no longer supported or a bug we will fix in .NET 5+.

For example, see #13192

@BickelLukas
Copy link
Author

@AaronRobinsonMSFT I did have a Breakthrough on this yesterday and was able to use the Library after all.

It might just have been a User error that could've been solved by better documentation or error messages.

I will provide more Information and a sample project first thing monday.

@BickelLukas
Copy link
Author

Here's a summary of the changes I made in order to get this to work.

  • Enable EmbedInteropTypes
  • Instantiate the interface instead of the class: clsMain instead of clsMainClass (Otherwise i get an error that the class cannot be embedded)

The weird thing is that without a reference type as a public field, I don't have to embed the interop types and can instantiate the class directly.

minimal Repro:
ComInteropRepro.zip

The Repro contains 2 C# and one VB6 Project.
I included the compiled VB6 binary dll inside the VB6 Folder. It needs to be registered via regsvr32.

The Solution contains 2 C# Winforms Projects targeting .NET 5.
One of them works while the other does not.

The only difference between the 2 Projects is that one has EmbedInteropTypes set to true while the other one has it set to false.
The code to instantiate the com class is in the codebehind of the Form1. I also provided some comments there.

@AaronRobinsonMSFT
Copy link
Member

/cc @elinor-fung

@elinor-fung elinor-fung removed the untriaged New issue has not been triaged by the area owner label Jul 9, 2021
@elinor-fung elinor-fung added this to the 6.0.0 milestone Jul 9, 2021
@elinor-fung
Copy link
Member

elinor-fung commented Jul 13, 2021

Alright - finally got to digging through this. @BickelLukas - thank you for the clear repro including the compiled VB6 binary - it was really helpful.

The actual error is on inspecting the _VTblGap* on ComInteropRepro._clsMain - 0x8013123b : Method is not marked static but is not HASTHIS or EXPLICITTHIS.

And indeed, the method is:

.method public specialname rtspecialname 
        void  _VtblGap8() runtime managed
{
} // end of method _clsMain::_VtblGap8

Whereas when it is embedded:

.method public specialname rtspecialname 
        instance void  _VtblGap1_1() runtime managed
{
} // end of method _clsMain::_VtblGap1_1

When running tlbimp.exe (from .NET Framework) on ComInteropRepro.dll directly, the method is also correctly marked as an instance method.

It is using the TypeLibConverter class that is problematic. The implementation of TypeLibConverter.ConvertTypeLibToAssembly ends up producing _VTblGap* methods that are not marked as static or instance, resulting in the failure in the .NET runtime.

By default, COMReference uses the TypeLibConverter in-proc instead of launching tlbimp.exe to generate the interop assembly. This can be configured through the ComReferenceExecuteAsTool, so a potential workaround (aside from embedding the types) is to set:

<PropertyGroup>
  <ComReferenceExecuteAsTool>true</ComReferenceExecuteAsTool>
</PropertyGroup>

Which will launch tlbimp.exe instead, such that the generated library won't fail validation.

In .NET Framework, the validation that is failing here was not done for _VTblGap* methods, since they aren't 'real' methods, but just indications for the correct vtable layout. But with beb215b, the signature validation was moved up such that we end up doing it for _VTblGap*.

We should be able to go back to skipping that validation for _VTblGap* methods.

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jul 14, 2021
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jul 14, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Aug 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants