public static partial void DoubleIntFieldsOutReturn(
IntFields input,
out IntFields result);
+
+ [GeneratedDllImport(NativeExportsNE_Binary, EntryPoint = "blittablestructs_increment_invert_ptrfields_byref")]
+ public static partial void IncrementInvertPointerFieldsByRef(ref PointerFields result);
+
+ [GeneratedDllImport(NativeExportsNE_Binary, EntryPoint = "blittablestructs_increment_invert_ptrfields_byref")]
+ public static partial void IncrementInvertPointerFieldsByRefIn(in PointerFields result);
+
+ [GeneratedDllImport(NativeExportsNE_Binary, EntryPoint = "blittablestructs_increment_invert_ptrfields_refreturn")]
+ public static partial void IncrementInvertPointerFieldsRefReturn(
+ PointerFields input,
+ ref PointerFields result);
}
public class BlittableStructTests
{
[Fact]
- public void ValidateBlittableStruct()
+ public void ValidateIntFields()
{
const int A = 24, B = 37, C = 59;
var initial = new IntFields()
Assert.Equal(expected, input); // Updated even when passed with in keyword (matches built-in system)
}
}
+
+ [Fact]
+ public unsafe void ValidatePointerFields()
+ {
+ int iInitial = 31;
+ bool bInitial = false;
+ char cInitial = 'A';
+
+ int iExpected = iInitial + 1;
+ bool bExpected = !bInitial;
+ char cExpected = (char)(cInitial + 1);
+
+ int i = iInitial;
+ bool b = bInitial;
+ char c = cInitial;
+ var initial = new PointerFields()
+ {
+ i = &i,
+ b = &b,
+ c = &c,
+ };
+
+ PointerFields input = initial;
+ {
+ int iResult;
+ bool bResult;
+ char cResult;
+ var result = new PointerFields()
+ {
+ i = &iResult,
+ b = &bResult,
+ c = &cResult
+ };
+ NativeExportsNE.IncrementInvertPointerFieldsRefReturn(input, ref result);
+ Assert.Equal(initial, input);
+ ValidateFieldValues(result);
+ }
+
+ {
+ ResetFieldValues(input);
+ NativeExportsNE.IncrementInvertPointerFieldsByRef(ref input);
+ Assert.Equal(initial, input);
+ ValidateFieldValues(input);
+ }
+
+ {
+ ResetFieldValues(input);
+ NativeExportsNE.IncrementInvertPointerFieldsByRefIn(in input);
+ Assert.Equal(initial, input);
+ ValidateFieldValues(input);
+ }
+
+ void ResetFieldValues(PointerFields input)
+ {
+ *(input.i) = iInitial;
+ *(input.b) = bInitial;
+ *(input.c) = cInitial;
+ }
+
+ void ValidateFieldValues(PointerFields result)
+ {
+ Assert.Equal(iExpected, *result.i);
+ Assert.Equal(bExpected, *result.b);
+ Assert.Equal(cExpected, *result.c);
+ }
+ }
}
}
}
[ConditionalFact]
- public async Task ValueTypeContainingPointerBlittableType_DoesNotReportDiagnostic()
+ public async Task ValueTypeContainingPointers_DoesNotReportDiagnostic()
{
var source = @"
using System.Runtime.InteropServices;
[BlittableType]
unsafe struct S
{
- private int* ptr;
+ private int* intPtr;
+ private bool* boolPtr;
}";
await VerifyCS.VerifyAnalyzerAsync(source);
}
[ConditionalFact]
- public async Task ValueTypeContainingPointerToNonBlittableType_ReportsDiagnostic()
- {
- var source = @"
-using System.Runtime.InteropServices;
-
-[{|#0:BlittableType|}]
-unsafe struct S
-{
- private bool* ptr;
-}";
- await VerifyCS.VerifyAnalyzerAsync(source,
- VerifyCS.Diagnostic(BlittableTypeMustBeBlittableRule).WithLocation(0).WithArguments("S"));
- }
-
- [ConditionalFact]
public async Task BlittableValueTypeContainingPointerToSelf_DoesNotReportDiagnostic()
{
result->b = input.b * 2;
result->c = input.c * 2;
}
+
+ [UnmanagedCallersOnly(EntryPoint = "blittablestructs_increment_invert_ptrfields_byref")]
+ [DNNE.C99DeclCode("struct ptr_fields { int* i; int* b; uint16_t* c; };")]
+ public static void IncrementInvertPointerFieldsByRef(
+ [DNNE.C99Type("struct ptr_fields*")] PointerFields* result)
+ {
+ *(result->i) += 1;
+ *(result->b) = !*(result->b);
+ *(result->c) += (char)1;
+ }
+
+ [UnmanagedCallersOnly(EntryPoint = "blittablestructs_increment_invert_ptrfields_refreturn")]
+ public static void IncrementInvertPointerFieldsRefReturn(
+ [DNNE.C99Type("struct ptr_fields")] PointerFields input,
+ [DNNE.C99Type("struct ptr_fields*")] PointerFields* result)
+ {
+ *(result->i) = *(input.i) + 1;
+ *(result->b) = !(*input.b);
+ *(result->c) = (char)(*(input.c) + 1);
+ }
}
}