From c23ef39bcad0780e03dbd3dce0c0a797eb8c7f0f Mon Sep 17 00:00:00 2001 From: Ali Alamiri Date: Fri, 17 Apr 2020 00:32:21 +0100 Subject: [PATCH] Marshal pointer to primitive typedefs in C++/CLI (#1355) Co-authored-by: Build Agent --- src/Generator/Generators/CLI/CLISources.cs | 17 +++++++++++++++-- tests/Common/Common.Tests.cs | 8 ++++++++ tests/Common/Common.cpp | 5 +++++ tests/Common/Common.h | 4 ++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/Generator/Generators/CLI/CLISources.cs b/src/Generator/Generators/CLI/CLISources.cs index 5b7541cd..1651ab15 100644 --- a/src/Generator/Generators/CLI/CLISources.cs +++ b/src/Generator/Generators/CLI/CLISources.cs @@ -1173,10 +1173,23 @@ namespace CppSharp.Generators.CLI var argName = Generator.GeneratedIdentifier("arg") + paramIndex.ToString(CultureInfo.InvariantCulture); var isRef = param.IsOut || param.IsInOut; + + var paramType = param.Type; + + // Get actual type if the param type is a typedef but not a function type because function types have to be typedef. + // We need to get the actual type this early before we visit any marshalling code to ensure we hit the marshalling + // logic for the actual type and not the typedef. + // This fixes issues where typedefs to primitive pointers are involved. + FunctionType functionType; + var paramTypeAsTypedef = paramType as TypedefType; + if (paramTypeAsTypedef != null && !paramTypeAsTypedef.Declaration.Type.IsPointerTo(out functionType)) + { + paramType = param.Type.Desugar(); + } + // Since both pointers and references to types are wrapped as CLI // tracking references when using in/out, we normalize them here to be able - // to use the same code for marshaling. - var paramType = param.Type; + // to use the same code for marshaling. if (paramType is PointerType && isRef) { if (!paramType.IsReference()) diff --git a/tests/Common/Common.Tests.cs b/tests/Common/Common.Tests.cs index 569417e1..f54e6de4 100644 --- a/tests/Common/Common.Tests.cs +++ b/tests/Common/Common.Tests.cs @@ -1095,4 +1095,12 @@ This is a very long string. This is a very long string. This is a very long stri const string @string = "string"; Assert.That(Common.TakeTypedefedMappedType(@string), Is.EqualTo(@string)); } + + [Test] + public void TestPointerToPrimitiveTypedefPointerTestMethod() + { + int a = 50; + Common.PointerToPrimitiveTypedefPointerTestMethod(ref a, 100); + Assert.AreEqual(100, a); + } } diff --git a/tests/Common/Common.cpp b/tests/Common/Common.cpp index b3c8e2c5..040d2d69 100644 --- a/tests/Common/Common.cpp +++ b/tests/Common/Common.cpp @@ -1215,3 +1215,8 @@ void DLL_API PointerToTypedefPointerTestMethod(LPPointerToTypedefPointerTest* lp { (*(*lp)).val = valToSet; } + +void DLL_API PointerToPrimitiveTypedefPointerTestMethod(LPINT lp, int valToSet) +{ + *lp = valToSet; +} diff --git a/tests/Common/Common.h b/tests/Common/Common.h index 56e0bdad..b22c8d1e 100644 --- a/tests/Common/Common.h +++ b/tests/Common/Common.h @@ -1616,3 +1616,7 @@ struct DLL_API PointerToTypedefPointerTest typedef PointerToTypedefPointerTest *LPPointerToTypedefPointerTest; void DLL_API PointerToTypedefPointerTestMethod(LPPointerToTypedefPointerTest* lp, int valToSet); + +typedef int *LPINT; + +void DLL_API PointerToPrimitiveTypedefPointerTestMethod(LPINT lp, int valToSet); \ No newline at end of file