diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs index 7129427e..d7414542 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs @@ -1545,7 +1545,14 @@ private void VisitRecordDecl(RecordDecl recordDecl) if (_config.GenerateExplicitVtbls) { - _outputBuilder.WriteRegularField("Vtbl*", "lpVtbl"); + if (_config.GenerateMarkerInterfaces && !_config.GenerateCompatibleCode) + { + _outputBuilder.WriteRegularField($"Vtbl<{nativeName}>*", "lpVtbl"); + } + else + { + _outputBuilder.WriteRegularField("Vtbl*", "lpVtbl"); + } } else { diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs index 29548200..48849f0c 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs @@ -37,6 +37,9 @@ public abstract class CXXMethodDeclarationTest : PInvokeGeneratorTest [Test] public Task NewKeywordVirtualWithExplicitVtblTest() => NewKeywordVirtualWithExplicitVtblTestImpl(); + [Test] + public Task NewKeywordVirtualWithExplicitVtblAndMarkerInterfaceTest() => NewKeywordVirtualWithExplicitVtblAndMarkerInterfaceTestImpl(); + [Test] public Task OperatorTest() => OperatorTestImpl(); @@ -118,6 +121,8 @@ public static int buf_close(void* pcontext) protected abstract Task NewKeywordVirtualWithExplicitVtblTestImpl(); + protected abstract Task NewKeywordVirtualWithExplicitVtblAndMarkerInterfaceTestImpl(); + protected abstract Task OperatorTestImpl(); protected abstract Task OperatorCallTestImpl(); diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs index bf3a699f..fe522fff 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs @@ -539,6 +539,91 @@ public partial struct Vtbl return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls); } + protected override Task NewKeywordVirtualWithExplicitVtblAndMarkerInterfaceTestImpl() + { + var inputContents = @"struct MyStruct +{ + virtual int GetType(int obj) = 0; + virtual int GetType() = 0; + virtual int GetType(int objA, int objB) = 0; +};"; + + var nativeCallConv = ""; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + nativeCallConv = " __attribute__((thiscall))"; + } + + var expectedOutputContents = $@"using System; +using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + public unsafe partial struct MyStruct : MyStruct.Interface + {{ + public Vtbl* lpVtbl; + + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] + public delegate int _GetType(MyStruct* pThis, int objA, int objB); + + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] + public delegate int _GetType1(MyStruct* pThis); + + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] + public delegate int _GetType2(MyStruct* pThis, int obj); + + public int GetType(int objA, int objB) + {{ + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType>(lpVtbl->GetType)(pThis, objA, objB); + }} + }} + + public new int GetType() + {{ + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType1>(lpVtbl->GetType1)(pThis); + }} + }} + + public int GetType(int obj) + {{ + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType2>(lpVtbl->GetType2)(pThis, obj); + }} + }} + + public interface Interface + {{ + int GetType(int objA, int objB); + + int GetType(); + + int GetType(int obj); + }} + + public partial struct Vtbl + {{ + [NativeTypeName(""int (int, int){nativeCallConv}"")] + public new IntPtr GetType; + + [NativeTypeName(""int (){nativeCallConv}"")] + public IntPtr GetType1; + + [NativeTypeName(""int (int){nativeCallConv}"")] + public IntPtr GetType2; + }} + }} +}} +"; + + return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls | PInvokeGeneratorConfigurationOptions.GenerateMarkerInterfaces); + } + protected override Task OperatorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs index 7df456b2..c1cfce53 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs @@ -539,6 +539,91 @@ public partial struct Vtbl return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls); } + protected override Task NewKeywordVirtualWithExplicitVtblAndMarkerInterfaceTestImpl() + { + var inputContents = @"struct MyStruct +{ + virtual int GetType(int obj) = 0; + virtual int GetType() = 0; + virtual int GetType(int objA, int objB) = 0; +};"; + + var nativeCallConv = ""; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + nativeCallConv = " __attribute__((thiscall))"; + } + + var expectedOutputContents = $@"using System; +using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + public unsafe partial struct MyStruct : MyStruct.Interface + {{ + public Vtbl* lpVtbl; + + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] + public delegate int _GetType(MyStruct* pThis, int objA, int objB); + + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] + public delegate int _GetType1(MyStruct* pThis); + + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] + public delegate int _GetType2(MyStruct* pThis, int obj); + + public int GetType(int objA, int objB) + {{ + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType>(lpVtbl->GetType)(pThis, objA, objB); + }} + }} + + public new int GetType() + {{ + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType1>(lpVtbl->GetType1)(pThis); + }} + }} + + public int GetType(int obj) + {{ + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType2>(lpVtbl->GetType2)(pThis, obj); + }} + }} + + public interface Interface + {{ + int GetType(int objA, int objB); + + int GetType(); + + int GetType(int obj); + }} + + public partial struct Vtbl + {{ + [NativeTypeName(""int (int, int){nativeCallConv}"")] + public new IntPtr GetType; + + [NativeTypeName(""int (){nativeCallConv}"")] + public IntPtr GetType1; + + [NativeTypeName(""int (int){nativeCallConv}"")] + public IntPtr GetType2; + }} + }} +}} +"; + + return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls | PInvokeGeneratorConfigurationOptions.GenerateMarkerInterfaces); + } + protected override Task OperatorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs index d0e094c9..eef855e4 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs @@ -501,6 +501,73 @@ public partial struct Vtbl return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls); } + protected override Task NewKeywordVirtualWithExplicitVtblAndMarkerInterfaceTestImpl() + { + var inputContents = @"struct MyStruct +{ + virtual int GetType(int obj) = 0; + virtual int GetType() = 0; + virtual int GetType(int objA, int objB) = 0; +};"; + + var nativeCallConv = ""; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + nativeCallConv = " __attribute__((thiscall))"; + } + + var expectedOutputContents = $@"using System.Runtime.CompilerServices; + +namespace ClangSharp.Test +{{ + public unsafe partial struct MyStruct : MyStruct.Interface + {{ + public Vtbl* lpVtbl; + + public int GetType(int objA, int objB) + {{ + return lpVtbl->GetType((MyStruct*)Unsafe.AsPointer(ref this), objA, objB); + }} + + public new int GetType() + {{ + return lpVtbl->GetType1((MyStruct*)Unsafe.AsPointer(ref this)); + }} + + public int GetType(int obj) + {{ + return lpVtbl->GetType2((MyStruct*)Unsafe.AsPointer(ref this), obj); + }} + + public interface Interface + {{ + int GetType(int objA, int objB); + + int GetType(); + + int GetType(int obj); + }} + + public partial struct Vtbl + where TSelf : unmanaged, Interface + {{ + [NativeTypeName(""int (int, int){nativeCallConv}"")] + public new delegate* unmanaged[Thiscall] GetType; + + [NativeTypeName(""int (){nativeCallConv}"")] + public delegate* unmanaged[Thiscall] GetType1; + + [NativeTypeName(""int (int){nativeCallConv}"")] + public delegate* unmanaged[Thiscall] GetType2; + }} + }} +}} +"; + + return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls | PInvokeGeneratorConfigurationOptions.GenerateMarkerInterfaces); + } + protected override Task OperatorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs index 9250aaec..e120f1d0 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs @@ -501,6 +501,73 @@ public partial struct Vtbl return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls); } + protected override Task NewKeywordVirtualWithExplicitVtblAndMarkerInterfaceTestImpl() + { + var inputContents = @"struct MyStruct +{ + virtual int GetType(int obj) = 0; + virtual int GetType() = 0; + virtual int GetType(int objA, int objB) = 0; +};"; + + var nativeCallConv = ""; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + nativeCallConv = " __attribute__((thiscall))"; + } + + var expectedOutputContents = $@"using System.Runtime.CompilerServices; + +namespace ClangSharp.Test +{{ + public unsafe partial struct MyStruct : MyStruct.Interface + {{ + public Vtbl* lpVtbl; + + public int GetType(int objA, int objB) + {{ + return lpVtbl->GetType((MyStruct*)Unsafe.AsPointer(ref this), objA, objB); + }} + + public new int GetType() + {{ + return lpVtbl->GetType1((MyStruct*)Unsafe.AsPointer(ref this)); + }} + + public int GetType(int obj) + {{ + return lpVtbl->GetType2((MyStruct*)Unsafe.AsPointer(ref this), obj); + }} + + public interface Interface + {{ + int GetType(int objA, int objB); + + int GetType(); + + int GetType(int obj); + }} + + public partial struct Vtbl + where TSelf : unmanaged, Interface + {{ + [NativeTypeName(""int (int, int){nativeCallConv}"")] + public new delegate* unmanaged[Thiscall] GetType; + + [NativeTypeName(""int (){nativeCallConv}"")] + public delegate* unmanaged[Thiscall] GetType1; + + [NativeTypeName(""int (int){nativeCallConv}"")] + public delegate* unmanaged[Thiscall] GetType2; + }} + }} +}} +"; + + return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls | PInvokeGeneratorConfigurationOptions.GenerateMarkerInterfaces); + } + protected override Task OperatorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs index 82c9ff9b..ddc1095e 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs @@ -655,6 +655,131 @@ protected override Task NewKeywordVirtualWithExplicitVtblTestImpl() return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls); } + protected override Task NewKeywordVirtualWithExplicitVtblAndMarkerInterfaceTestImpl() + { + var inputContents = @"struct MyStruct +{ + virtual int GetType(int obj) = 0; + virtual int GetType() = 0; + virtual int GetType(int objA, int objB) = 0; +};"; + + var nativeCallConv = ""; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + nativeCallConv = " __attribute__((thiscall))"; + } + + var expectedOutputContents = $@" + + + + + Vtbl* + + + int + + MyStruct* + + + int + + + int + + + + int + + MyStruct* + + + + int + + MyStruct* + + + int + + + + int + + int + + + int + + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType>(lpVtbl->GetType)(pThis, objA, objB); + }} + + + + int + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType1>(lpVtbl->GetType1)(pThis); + }} + + + + int + + int + + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType2>(lpVtbl->GetType2)(pThis, obj); + }} + + + + + int + + int + + + int + + + + int + + + int + + int + + + + + + IntPtr + + + IntPtr + + + IntPtr + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls | PInvokeGeneratorConfigurationOptions.GenerateMarkerInterfaces); + } + protected override Task OperatorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs index 15f76b42..cc69ee41 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs @@ -655,6 +655,131 @@ protected override Task NewKeywordVirtualWithExplicitVtblTestImpl() return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls); } + protected override Task NewKeywordVirtualWithExplicitVtblAndMarkerInterfaceTestImpl() + { + var inputContents = @"struct MyStruct +{ + virtual int GetType(int obj) = 0; + virtual int GetType() = 0; + virtual int GetType(int objA, int objB) = 0; +};"; + + var nativeCallConv = ""; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + nativeCallConv = " __attribute__((thiscall))"; + } + + var expectedOutputContents = $@" + + + + + Vtbl* + + + int + + MyStruct* + + + int + + + int + + + + int + + MyStruct* + + + + int + + MyStruct* + + + int + + + + int + + int + + + int + + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType>(lpVtbl->GetType)(pThis, objA, objB); + }} + + + + int + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType1>(lpVtbl->GetType1)(pThis); + }} + + + + int + + int + + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType2>(lpVtbl->GetType2)(pThis, obj); + }} + + + + + int + + int + + + int + + + + int + + + int + + int + + + + + + IntPtr + + + IntPtr + + + IntPtr + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls | PInvokeGeneratorConfigurationOptions.GenerateMarkerInterfaces); + } + protected override Task OperatorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs index 488d73a7..a3b0adde 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs @@ -583,6 +583,95 @@ protected override Task NewKeywordVirtualWithExplicitVtblTestImpl() return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls); } + protected override Task NewKeywordVirtualWithExplicitVtblAndMarkerInterfaceTestImpl() + { + var inputContents = @"struct MyStruct +{ + virtual int GetType(int obj) = 0; + virtual int GetType() = 0; + virtual int GetType(int objA, int objB) = 0; +};"; + + var nativeCallConv = ""; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + nativeCallConv = " __attribute__((thiscall))"; + } + + var expectedOutputContents = $@" + + + + + Vtbl<MyStruct>* + + + int + + int + + + int + + + return lpVtbl->GetType((MyStruct*)Unsafe.AsPointer(ref this), objA, objB); + + + + int + + return lpVtbl->GetType1((MyStruct*)Unsafe.AsPointer(ref this)); + + + + int + + int + + + return lpVtbl->GetType2((MyStruct*)Unsafe.AsPointer(ref this), obj); + + + + + int + + int + + + int + + + + int + + + int + + int + + + + + + delegate* unmanaged[Thiscall]<TSelf*, int, int, int> + + + delegate* unmanaged[Thiscall]<TSelf*, int> + + + delegate* unmanaged[Thiscall]<TSelf*, int, int> + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls | PInvokeGeneratorConfigurationOptions.GenerateMarkerInterfaces); + } + protected override Task OperatorTestImpl() { var inputContents = @"struct MyStruct diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs index 2ef8878d..c480d7bf 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs @@ -583,6 +583,95 @@ protected override Task NewKeywordVirtualWithExplicitVtblTestImpl() return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls); } + protected override Task NewKeywordVirtualWithExplicitVtblAndMarkerInterfaceTestImpl() + { + var inputContents = @"struct MyStruct +{ + virtual int GetType(int obj) = 0; + virtual int GetType() = 0; + virtual int GetType(int objA, int objB) = 0; +};"; + + var nativeCallConv = ""; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + nativeCallConv = " __attribute__((thiscall))"; + } + + var expectedOutputContents = $@" + + + + + Vtbl<MyStruct>* + + + int + + int + + + int + + + return lpVtbl->GetType((MyStruct*)Unsafe.AsPointer(ref this), objA, objB); + + + + int + + return lpVtbl->GetType1((MyStruct*)Unsafe.AsPointer(ref this)); + + + + int + + int + + + return lpVtbl->GetType2((MyStruct*)Unsafe.AsPointer(ref this), obj); + + + + + int + + int + + + int + + + + int + + + int + + int + + + + + + delegate* unmanaged[Thiscall]<TSelf*, int, int, int> + + + delegate* unmanaged[Thiscall]<TSelf*, int> + + + delegate* unmanaged[Thiscall]<TSelf*, int, int> + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls | PInvokeGeneratorConfigurationOptions.GenerateMarkerInterfaces); + } + protected override Task OperatorTestImpl() { var inputContents = @"struct MyStruct