Skip to content

Commit c23ef39

Browse files
IIFEBuild Agent
andauthored
Marshal pointer to primitive typedefs in C++/CLI (#1355)
Co-authored-by: Build Agent <[email protected]>
1 parent 116ee82 commit c23ef39

File tree

4 files changed

+32
-2
lines changed

4 files changed

+32
-2
lines changed

src/Generator/Generators/CLI/CLISources.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,10 +1173,23 @@ private ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramInde
11731173
var argName = Generator.GeneratedIdentifier("arg") + paramIndex.ToString(CultureInfo.InvariantCulture);
11741174

11751175
var isRef = param.IsOut || param.IsInOut;
1176+
1177+
var paramType = param.Type;
1178+
1179+
// Get actual type if the param type is a typedef but not a function type because function types have to be typedef.
1180+
// We need to get the actual type this early before we visit any marshalling code to ensure we hit the marshalling
1181+
// logic for the actual type and not the typedef.
1182+
// This fixes issues where typedefs to primitive pointers are involved.
1183+
FunctionType functionType;
1184+
var paramTypeAsTypedef = paramType as TypedefType;
1185+
if (paramTypeAsTypedef != null && !paramTypeAsTypedef.Declaration.Type.IsPointerTo(out functionType))
1186+
{
1187+
paramType = param.Type.Desugar();
1188+
}
1189+
11761190
// Since both pointers and references to types are wrapped as CLI
11771191
// tracking references when using in/out, we normalize them here to be able
1178-
// to use the same code for marshaling.
1179-
var paramType = param.Type;
1192+
// to use the same code for marshaling.
11801193
if (paramType is PointerType && isRef)
11811194
{
11821195
if (!paramType.IsReference())

tests/Common/Common.Tests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,4 +1095,12 @@ public void TestTakeTypedefedMappedType()
10951095
const string @string = "string";
10961096
Assert.That(Common.TakeTypedefedMappedType(@string), Is.EqualTo(@string));
10971097
}
1098+
1099+
[Test]
1100+
public void TestPointerToPrimitiveTypedefPointerTestMethod()
1101+
{
1102+
int a = 50;
1103+
Common.PointerToPrimitiveTypedefPointerTestMethod(ref a, 100);
1104+
Assert.AreEqual(100, a);
1105+
}
10981106
}

tests/Common/Common.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,3 +1215,8 @@ void DLL_API PointerToTypedefPointerTestMethod(LPPointerToTypedefPointerTest* lp
12151215
{
12161216
(*(*lp)).val = valToSet;
12171217
}
1218+
1219+
void DLL_API PointerToPrimitiveTypedefPointerTestMethod(LPINT lp, int valToSet)
1220+
{
1221+
*lp = valToSet;
1222+
}

tests/Common/Common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,3 +1616,7 @@ struct DLL_API PointerToTypedefPointerTest
16161616
typedef PointerToTypedefPointerTest *LPPointerToTypedefPointerTest;
16171617

16181618
void DLL_API PointerToTypedefPointerTestMethod(LPPointerToTypedefPointerTest* lp, int valToSet);
1619+
1620+
typedef int *LPINT;
1621+
1622+
void DLL_API PointerToPrimitiveTypedefPointerTestMethod(LPINT lp, int valToSet);

0 commit comments

Comments
 (0)