* Don't block non-blittable pointer types in P/Invokes.
Don't block non-blittable pointer types in P/Invokes. If you're using pointers in interop you're already using unsafe code so we're going to assume you know what you're doing. C# won't let you form a pointer to a reference, so there's no risk of passing an object reference directly to native unless you're writing IL directly.
Fixes dotnet/coreclr#27800
* Delete unused resources.
* Apply fix to managed type system as well.
* Add positive test for nonblittable pointers. Remove negative tests that were in GenericTest.
IDS_EE_BADMARSHAL_SAFEHANDLEARRAY "Invalid managed/unmanaged type combination (Arrays of SafeHandles are not supported)."
IDS_EE_BADMARSHAL_CRITICALHANDLEARRAY "Invalid managed/unmanaged type combination (Arrays of CriticalHandles are not supported)."
IDS_EE_BADMARSHAL_SYSARRAY "Invalid managed/unmanaged type combination (System.Array must be paired with SafeArray or Interface)."
- IDS_EE_BADMARSHAL_PTRSUBTYPE "Pointers cannot reference managed objects. Use ByRef instead."
- IDS_EE_BADMARSHAL_PTRNONBLITTABLE "Pointers cannot reference marshaled structures. Use ByRef instead."
IDS_EE_BADMARSHAL_RESTRICTION "This type can only be marshaled in restricted ways."
IDS_EE_BADMARSHAL_ASANYRESTRICTION "AsAny cannot be used on return types, ByRef parameters, ArrayWithOffset, or parameters passed from unmanaged to managed."
IDS_EE_BADMARSHAL_VBBYVALSTRRESTRICTION "VBByRefStr can only be used in combination with in/out, ByRef managed-to-unmanaged strings."
#define IDS_EE_BADMARSHAL_BADMANAGED 0x1756
#define IDS_EE_SRC_OBJ_NOT_COMOBJECT 0x1757
#define IDS_EE_CANNOT_COERCE_COMOBJECT 0x1759
-#define IDS_EE_BADMARSHAL_PTRSUBTYPE 0x175b
-#define IDS_EE_BADMARSHAL_PTRNONBLITTABLE 0x175c
#define IDS_EE_BADMARSHAL_RESTRICTION 0x175d
#define IDS_EE_BADMARSHAL_ASANYRESTRICTION 0x175f
{
public static partial class MarshalHelpers
{
- internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type,
- MarshallerKind kind,
+ internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type,
+ MarshallerKind kind,
MarshallerKind elementMarshallerKind,
#if !READYTORUN
InteropStateManager interopStateManager,
#if !READYTORUN
interopStateManager,
#endif
- marshalAs,
+ marshalAs,
isArrayElement: true);
return elementNativeType.MakePointerType();
}
else if (type.IsPointer)
{
-#if READYTORUN
- TypeDesc parameterType = ((PointerType)type).ParameterType;
-
- if ((!parameterType.IsEnum
- && !parameterType.IsPrimitive
- && !MarshalUtils.IsBlittableType(parameterType))
- || parameterType.IsGCPointer)
- {
- // Pointers cannot reference marshaled structures. Use ByRef instead.
- return MarshallerKind.Invalid;
- }
-#else
- // Do not bother enforcing the above artificial restriction
- // See https://github.com/dotnet/coreclr/issues/27800
-#endif
-
if (nativeType == NativeTypeKind.Default)
return MarshallerKind.BlittableValue;
else
// plus they are not marked as blittable.
if (!th.IsEnum())
{
- // It should be blittable
- if (!th.IsBlittable())
- {
- m_resID = IDS_EE_BADMARSHAL_PTRNONBLITTABLE;
- IfFailGoto(E_FAIL, lFail);
- }
-
// Check for Copy Constructor Modifier
if (sigtmp.HasCustomModifier(pModule, "Microsoft.VisualC.NeedsCopyConstructorModifier", ELEMENT_TYPE_CMOD_REQD) ||
sigtmp.HasCustomModifier(pModule, "System.Runtime.CompilerServices.IsCopyConstructed", ELEMENT_TYPE_CMOD_REQD) )
}
}
}
- else
- {
- if (!(mtype2 != ELEMENT_TYPE_CLASS &&
- mtype2 != ELEMENT_TYPE_STRING &&
- mtype2 != ELEMENT_TYPE_OBJECT &&
- mtype2 != ELEMENT_TYPE_SZARRAY))
- {
- m_resID = IDS_EE_BADMARSHAL_PTRSUBTYPE;
- IfFailGoto(E_FAIL, lFail);
- }
- }
}
}
add_subdirectory(PInvoke/Delegate)
add_subdirectory(PInvoke/Primitives/Int)
add_subdirectory(PInvoke/Primitives/RuntimeHandles)
+add_subdirectory(PInvoke/Primitives/Pointer)
add_subdirectory(PInvoke/SizeParamIndex/PInvoke/PassingByOut)
add_subdirectory(PInvoke/SizeParamIndex/PInvoke/PassingByRef)
add_subdirectory(PInvoke/SizeParamIndex/ReversePInvoke/PassingByOut)
public static extern bool? GetNullableB(bool hasValue, bool value);
[DllImport(nameof(GenericsNative))]
- public static extern void GetNullableBOut(bool hasValue, bool value, bool?* pValue);
-
- [DllImport(nameof(GenericsNative))]
public static extern void GetNullableBOut(bool hasValue, bool value, out bool? pValue);
- [DllImport(nameof(GenericsNative))]
- public static extern bool?* GetNullableBPtr(bool hasValue, bool value);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetNullableBPtr")]
public static extern ref readonly bool? GetNullableBRef(bool hasValue, bool value);
public static extern bool? AddNullableB(bool? lhs, bool? rhs);
[DllImport(nameof(GenericsNative))]
- public static extern bool? AddNullableBs(bool?* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern bool? AddNullableBs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] bool?[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableB(true, false));
- Assert.Throws<MarshalDirectiveException>(() => {
- bool? value2;
- GenericsNative.GetNullableBOut(true, false, &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableBOut(true, false, out bool? value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableBPtr(true, false));
-
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableBRef(true, false));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableB(default, default));
bool?[] values = new bool?[] {
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (bool?* pValues = &values[0])
- {
- GenericsNative.AddNullableBs(pValues, values.Length);
- }
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableBs(values, values.Length));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableBs(in values[0], values.Length));
public static extern char? GetNullableC(bool hasValue, char value);
[DllImport(nameof(GenericsNative))]
- public static extern void GetNullableCOut(bool hasValue, char value, char?* pValue);
-
- [DllImport(nameof(GenericsNative))]
public static extern void GetNullableCOut(bool hasValue, char value, out char? pValue);
- [DllImport(nameof(GenericsNative))]
- public static extern char?* GetNullableCPtr(bool hasValue, char value);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetNullableCPtr")]
public static extern ref readonly char? GetNullableCRef(bool hasValue, char value);
public static extern char? AddNullableC(char? lhs, char? rhs);
[DllImport(nameof(GenericsNative))]
- public static extern char? AddNullableCs(char?* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern char? AddNullableCs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] char?[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableC(true, '1'));
- Assert.Throws<MarshalDirectiveException>(() => {
- char? value2;
- GenericsNative.GetNullableCOut(true, '1', &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableCOut(true, '1', out char? value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableCPtr(true, '1'));
-
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableCRef(true, '1'));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableC(default, default));
char?[] values = new char?[] {
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (char?* pValues = &values[0])
- {
- GenericsNative.AddNullableCs(pValues, values.Length);
- }
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableCs(values, values.Length));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableCs(in values[0], values.Length));
public static extern double? GetNullableD(bool hasValue, double value);
[DllImport(nameof(GenericsNative))]
- public static extern void GetNullableDOut(bool hasValue, double value, double?* pValue);
-
- [DllImport(nameof(GenericsNative))]
public static extern void GetNullableDOut(bool hasValue, double value, out double? pValue);
- [DllImport(nameof(GenericsNative))]
- public static extern double?* GetNullableDPtr(bool hasValue, double value);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetNullableDPtr")]
public static extern ref readonly double? GetNullableDRef(bool hasValue, double value);
public static extern double? AddNullableD(double? lhs, double? rhs);
[DllImport(nameof(GenericsNative))]
- public static extern double? AddNullableDs(double?* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern double? AddNullableDs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] double?[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableD(true, 1.0));
- Assert.Throws<MarshalDirectiveException>(() => {
- double? value2;
- GenericsNative.GetNullableDOut(true, 1.0, &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableDOut(true, 1.0, out double? value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableDPtr(true, 1.0));
-
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableDRef(true, 1.0));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableD(default, default));
double?[] values = new double?[] {
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (double?* pValues = &values[0])
- {
- GenericsNative.AddNullableDs(pValues, values.Length);
- }
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableDs(values, values.Length));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableDs(in values[0], values.Length));
{
[DllImport(nameof(GenericsNative))]
public static extern float? GetNullableF(bool hasValue, float value);
-
- [DllImport(nameof(GenericsNative))]
- public static extern void GetNullableFOut(bool hasValue, float value, float?* pValue);
-
[DllImport(nameof(GenericsNative))]
public static extern void GetNullableFOut(bool hasValue, float value, out float? pValue);
- [DllImport(nameof(GenericsNative))]
- public static extern float?* GetNullableFPtr(bool hasValue, float value);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetNullableFPtr")]
public static extern ref readonly float? GetNullableFRef(bool hasValue, float value);
public static extern float? AddNullableF(float? lhs, float? rhs);
[DllImport(nameof(GenericsNative))]
- public static extern float? AddNullableFs(float?* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern float? AddNullableFs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] float?[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableF(true, 1.0f));
- Assert.Throws<MarshalDirectiveException>(() => {
- float? value2;
- GenericsNative.GetNullableFOut(true, 1.0f, &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableFOut(true, 1.0f, out float? value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableFPtr(true, 1.0f));
-
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableFRef(true, 1.0f));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableF(default, default));
float?[] values = new float?[] {
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (float?* pValues = &values[0])
- {
- GenericsNative.AddNullableFs(pValues, values.Length);
- }
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableFs(values, values.Length));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableFs(in values[0], values.Length));
public static extern long? GetNullableL(bool hasValue, long value);
[DllImport(nameof(GenericsNative))]
- public static extern void GetNullableLOut(bool hasValue, long value, long?* pValue);
-
- [DllImport(nameof(GenericsNative))]
public static extern void GetNullableLOut(bool hasValue, long value, out long? pValue);
- [DllImport(nameof(GenericsNative))]
- public static extern long?* GetNullableLPtr(bool hasValue, long value);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetNullableLPtr")]
public static extern ref readonly long? GetNullableLRef(bool hasValue, long value);
public static extern long? AddNullableL(long? lhs, long? rhs);
[DllImport(nameof(GenericsNative))]
- public static extern long? AddNullableLs(long?* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern long? AddNullableLs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] long?[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableL(true, 1L));
- Assert.Throws<MarshalDirectiveException>(() => {
- long? value2;
- GenericsNative.GetNullableLOut(true, 1L, &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableLOut(true, 1L, out long? value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableLPtr(true, 1L));
-
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableLRef(true, 1L));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableL(default, default));
long?[] values = new long?[] {
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (long?* pValues = &values[0])
- {
- GenericsNative.AddNullableLs(pValues, values.Length);
- }
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableLs(values, values.Length));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableLs(in values[0], values.Length));
public static extern uint? GetNullableU(bool hasValue, uint value);
[DllImport(nameof(GenericsNative))]
- public static extern void GetNullableUOut(bool hasValue, uint value, uint?* pValue);
-
- [DllImport(nameof(GenericsNative))]
public static extern void GetNullableUOut(bool hasValue, uint value, out uint? pValue);
- [DllImport(nameof(GenericsNative))]
- public static extern uint?* GetNullableUPtr(bool hasValue, uint value);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetNullableUPtr")]
public static extern ref readonly uint? GetNullableURef(bool hasValue, uint value);
public static extern uint? AddNullableU(uint? lhs, uint? rhs);
[DllImport(nameof(GenericsNative))]
- public static extern uint? AddNullableUs(uint?* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern uint? AddNullableUs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] uint?[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableU(true, 1u));
- Assert.Throws<MarshalDirectiveException>(() => {
- uint? value2;
- GenericsNative.GetNullableUOut(true, 1u, &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableUOut(true, 1u, out uint? value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableUPtr(true, 1u));
-
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableURef(true, 1u));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableU(default, default));
uint?[] values = new uint?[] {
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (uint?* pValues = &values[0])
- {
- GenericsNative.AddNullableUs(pValues, values.Length);
- }
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableUs(values, values.Length));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableUs(in values[0], values.Length));
public static extern Point1<bool> GetPoint1B(bool e00);
[DllImport(nameof(GenericsNative))]
- public static extern void GetPoint1BOut(bool e00, Point1<bool>* value);
-
- [DllImport(nameof(GenericsNative))]
public static extern void GetPoint1BOut(bool e00, out Point1<bool> value);
- [DllImport(nameof(GenericsNative))]
- public static extern Point1<bool>* GetPoint1BPtr(bool e00);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetPoint1BPtr")]
public static extern ref readonly Point1<bool> GetPoint1BRef(bool e00);
public static extern Point1<bool> AddPoint1B(Point1<bool> lhs, Point1<bool> rhs);
[DllImport(nameof(GenericsNative))]
- public static extern Point1<bool> AddPoint1Bs(Point1<bool>* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern Point1<bool> AddPoint1Bs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point1<bool>[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1B(true));
- Assert.Throws<MarshalDirectiveException>(() => {
- GenericsNative.Point1<bool> value2;
- GenericsNative.GetPoint1BOut(true, &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1BOut(true, out GenericsNative.Point1<bool> value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1BPtr(true));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1BRef(true));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint1B(default, default));
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (GenericsNative.Point1<bool>* pValues = &values[0])
- {
- GenericsNative.AddPoint1Bs(pValues, values.Length);
- }
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint1Bs(values, values.Length));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint1Bs(in values[0], values.Length));
public static extern Point1<char> GetPoint1C(char e00);
[DllImport(nameof(GenericsNative))]
- public static extern void GetPoint1COut(char e00, Point1<char>* value);
-
- [DllImport(nameof(GenericsNative))]
public static extern void GetPoint1COut(char e00, out Point1<char> value);
- [DllImport(nameof(GenericsNative))]
- public static extern Point1<char>* GetPoint1CPtr(char e00);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetPoint1CPtr")]
public static extern ref readonly Point1<char> GetPoint1CRef(char e00);
public static extern Point1<char> AddPoint1C(Point1<char> lhs, Point1<char> rhs);
[DllImport(nameof(GenericsNative))]
- public static extern Point1<char> AddPoint1Cs(Point1<char>* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern Point1<char> AddPoint1Cs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point1<char>[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1C('1'));
- Assert.Throws<MarshalDirectiveException>(() => {
- GenericsNative.Point1<char> value2;
- GenericsNative.GetPoint1COut('1', &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1COut('1', out GenericsNative.Point1<char> value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1CPtr('1'));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1CRef('1'));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint1C(default, default));
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (GenericsNative.Point1<char>* pValues = &values[0])
- {
- GenericsNative.AddPoint1Cs(pValues, values.Length);
- }
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint1Cs(values, values.Length));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint1Cs(in values[0], values.Length));
public static extern Point2<bool> GetPoint2B(bool e00, bool e01);
[DllImport(nameof(GenericsNative))]
- public static extern void GetPoint2BOut(bool e00, bool e01, Point2<bool>* value);
-
- [DllImport(nameof(GenericsNative))]
public static extern void GetPoint2BOut(bool e00, bool e01, out Point2<bool> value);
- [DllImport(nameof(GenericsNative))]
- public static extern Point2<bool>* GetPoint2BPtr(bool e00, bool e01);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetPoint2BPtr")]
public static extern ref readonly Point2<bool> GetPoint2BRef(bool e00, bool e01);
public static extern Point2<bool> AddPoint2B(Point2<bool> lhs, Point2<bool> rhs);
[DllImport(nameof(GenericsNative))]
- public static extern Point2<bool> AddPoint2Bs(Point2<bool>* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern Point2<bool> AddPoint2Bs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point2<bool>[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2B(true, false));
- Assert.Throws<MarshalDirectiveException>(() => {
- GenericsNative.Point2<bool> value2;
- GenericsNative.GetPoint2BOut(true, false, &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2BOut(true, false, out GenericsNative.Point2<bool> value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2BPtr(true, false));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2BRef(true, false));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint2B(default, default));
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (GenericsNative.Point2<bool>* pValues = &values[0])
- {
- GenericsNative.AddPoint2Bs(pValues, values.Length);
- }
- });
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint2Bs(values, values.Length));
public static extern Point2<char> GetPoint2C(char e00, char e01);
[DllImport(nameof(GenericsNative))]
- public static extern void GetPoint2COut(char e00, char e01, Point2<char>* value);
-
- [DllImport(nameof(GenericsNative))]
public static extern void GetPoint2COut(char e00, char e01, out Point2<char> value);
- [DllImport(nameof(GenericsNative))]
- public static extern Point2<char>* GetPoint2CPtr(char e00, char e01);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetPoint2CPtr")]
public static extern ref readonly Point2<char> GetPoint2CRef(char e00, char e01);
public static extern Point2<char> AddPoint2C(Point2<char> lhs, Point2<char> rhs);
[DllImport(nameof(GenericsNative))]
- public static extern Point2<char> AddPoint2Cs(Point2<char>* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern Point2<char> AddPoint2Cs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point2<char>[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2C('1', '2'));
- Assert.Throws<MarshalDirectiveException>(() => {
- GenericsNative.Point2<char> value2;
- GenericsNative.GetPoint2COut('1', '2', &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2COut('1', '2', out GenericsNative.Point2<char> value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2CPtr('1', '2'));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2CRef('1', '2'));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint2C(default, default));
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (GenericsNative.Point2<char>* pValues = &values[0])
- {
- GenericsNative.AddPoint2Cs(pValues, values.Length);
- }
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint2Cs(values, values.Length));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint2Cs(in values[0], values.Length));
public static extern Point3<bool> GetPoint3B(bool e00, bool e01, bool e02);
[DllImport(nameof(GenericsNative))]
- public static extern void GetPoint3BOut(bool e00, bool e01, bool e02, Point3<bool>* value);
-
- [DllImport(nameof(GenericsNative))]
public static extern void GetPoint3BOut(bool e00, bool e01, bool e02, out Point3<bool> value);
- [DllImport(nameof(GenericsNative))]
- public static extern Point3<bool>* GetPoint3BPtr(bool e00, bool e01, bool e02);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetPoint3BPtr")]
public static extern ref readonly Point3<bool> GetPoint3BRef(bool e00, bool e01, bool e02);
public static extern Point3<bool> AddPoint3B(Point3<bool> lhs, Point3<bool> rhs);
[DllImport(nameof(GenericsNative))]
- public static extern Point3<bool> AddPoint3Bs(Point3<bool>* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern Point3<bool> AddPoint3Bs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point3<bool>[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3B(true, false, true));
- Assert.Throws<MarshalDirectiveException>(() => {
- GenericsNative.Point3<bool> value2;
- GenericsNative.GetPoint3BOut(true, false, true, &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3BOut(true, false, true, out GenericsNative.Point3<bool> value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3BPtr(true, false, true));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3BRef(true, false, true));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint3B(default, default));
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (GenericsNative.Point3<bool>* pValues = &values[0])
- {
- GenericsNative.AddPoint3Bs(pValues, values.Length);
- }
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint3Bs(values, values.Length));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint3Bs(in values[0], values.Length));
public static extern Point3<char> GetPoint3C(char e00, char e01, char e02);
[DllImport(nameof(GenericsNative))]
- public static extern void GetPoint3COut(char e00, char e01, char e02, Point3<char>* value);
-
- [DllImport(nameof(GenericsNative))]
public static extern void GetPoint3COut(char e00, char e01, char e02, out Point3<char> value);
- [DllImport(nameof(GenericsNative))]
- public static extern Point3<char>* GetPoint3CPtr(char e00, char e01, char e02);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetPoint3CPtr")]
public static extern ref readonly Point3<char> GetPoint3CRef(char e00, char e01, char e02);
public static extern Point3<char> AddPoint3C(Point3<char> lhs, Point3<char> rhs);
[DllImport(nameof(GenericsNative))]
- public static extern Point3<char> AddPoint3Cs(Point3<char>* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern Point3<char> AddPoint3Cs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point3<char>[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3C('1', '2', '3'));
- Assert.Throws<MarshalDirectiveException>(() => {
- GenericsNative.Point3<char> value2;
- GenericsNative.GetPoint3COut('1', '2', '3', &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3COut('1', '2', '3', out GenericsNative.Point3<char> value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3CPtr('1', '2', '3'));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3CRef('1', '2', '3'));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint3C(default, default));
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (GenericsNative.Point3<char>* pValues = &values[0])
- {
- GenericsNative.AddPoint3Cs(pValues, values.Length);
- }
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint3Cs(values, values.Length));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint3Cs(in values[0], values.Length));
public static extern Point4<bool> GetPoint4B(bool e00, bool e01, bool e02, bool e03);
[DllImport(nameof(GenericsNative))]
- public static extern void GetPoint4BOut(bool e00, bool e01, bool e02, bool e03, Point4<bool>* value);
-
- [DllImport(nameof(GenericsNative))]
public static extern void GetPoint4BOut(bool e00, bool e01, bool e02, bool e03, out Point4<bool> value);
- [DllImport(nameof(GenericsNative))]
- public static extern Point4<bool>* GetPoint4BPtr(bool e00, bool e01, bool e02, bool e03);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetPoint4BPtr")]
public static extern ref readonly Point4<bool> GetPoint4BRef(bool e00, bool e01, bool e02, bool e03);
public static extern Point4<bool> AddPoint4B(Point4<bool> lhs, Point4<bool> rhs);
[DllImport(nameof(GenericsNative))]
- public static extern Point4<bool> AddPoint4Bs(Point4<bool>* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern Point4<bool> AddPoint4Bs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point4<bool>[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4B(true, false, true, false));
- Assert.Throws<MarshalDirectiveException>(() => {
- GenericsNative.Point4<bool> value2;
- GenericsNative.GetPoint4BOut(true, false, true, false, &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4BOut(true, false, true, false, out GenericsNative.Point4<bool> value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4BPtr(true, false, true, false));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4BRef(true, false, true, false));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint4B(default, default));
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (GenericsNative.Point4<bool>* pValues = &values[0])
- {
- GenericsNative.AddPoint4Bs(pValues, values.Length);
- }
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint4Bs(values, values.Length));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint4Bs(in values[0], values.Length));
public static extern Point4<char> GetPoint4C(char e00, char e01, char e02, char e03);
[DllImport(nameof(GenericsNative))]
- public static extern void GetPoint4COut(char e00, char e01, char e02, char e03, Point4<char>* value);
-
- [DllImport(nameof(GenericsNative))]
public static extern void GetPoint4COut(char e00, char e01, char e02, char e03, out Point4<char> value);
- [DllImport(nameof(GenericsNative))]
- public static extern Point4<char>* GetPoint4CPtr(char e00, char e01, char e02, char e03);
-
[DllImport(nameof(GenericsNative), EntryPoint = "GetPoint4CPtr")]
public static extern ref readonly Point4<char> GetPoint4CRef(char e00, char e01, char e02, char e03);
public static extern Point4<char> AddPoint4C(Point4<char> lhs, Point4<char> rhs);
[DllImport(nameof(GenericsNative))]
- public static extern Point4<char> AddPoint4Cs(Point4<char>* pValues, int count);
-
- [DllImport(nameof(GenericsNative))]
public static extern Point4<char> AddPoint4Cs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point4<char>[] pValues, int count);
[DllImport(nameof(GenericsNative))]
{
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4C('1', '2', '3', '4'));
- Assert.Throws<MarshalDirectiveException>(() => {
- GenericsNative.Point4<char> value2;
- GenericsNative.GetPoint4COut('1', '2', '3', '4', &value2);
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4COut('1', '2', '3', '4', out GenericsNative.Point4<char> value3));
- Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4CPtr('1', '2', '3', '4'));
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4CRef('1', '2', '3', '4'));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint4C(default, default));
default
};
- Assert.Throws<MarshalDirectiveException>(() => {
- fixed (GenericsNative.Point4<char>* pValues = &values[0])
- {
- GenericsNative.AddPoint4Cs(pValues, values.Length);
- }
- });
-
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint4Cs(values, values.Length));
Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint4Cs(in values[0], values.Length));
--- /dev/null
+include ("${CLR_INTEROP_TEST_ROOT}/Interop.cmake")
+set(SOURCES
+ NonBlittablePointerNative.cpp
+)
+add_library (NonBlittablePointerNative SHARED ${SOURCES})
+install (TARGETS NonBlittablePointerNative DESTINATION bin)
<Project Sdk="Microsoft.NET.Sdk">
+
<PropertyGroup>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
+
<ItemGroup>
- <Compile Include="PInvokePointerTest.cs" />
+ <Compile Include="Program.cs" />
+ <ProjectReference Include="CMakeLists.txt" />
</ItemGroup>
+
<Import Project="$([MSBuild]::GetPathOfFileAbove(Interop.settings.targets))" />
</Project>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include <xplatform.h>
+
+extern "C" DLL_EXPORT void STDMETHODCALLTYPE Negate(bool* ptr)
+{
+ *ptr = !*ptr;
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Runtime.InteropServices;
-using TestLibrary;
-
-unsafe class Program
-{
- [StructLayout(LayoutKind.Sequential)]
- struct NonBlittable
- {
- bool _nonBlittable;
- }
-
- // the "string unused" parameter is just so that we don't hit https://github.com/dotnet/coreclr/issues/27408 that
- // makes this p/invoke actually work.
- [DllImport("Unused")]
- private static extern void PointerToNonBlittableType(NonBlittable* pNonBlittable, string unused);
-
- static int Main()
- {
- Assert.Throws<MarshalDirectiveException>(() => PointerToNonBlittableType(null, null));
-
- return 100;
- }
-}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace NonBlittablePointer
+{
+ static class NonBlittablePointerNative
+ {
+ [DllImport(nameof(NonBlittablePointerNative))]
+ public static unsafe extern void Negate(bool* ptr);
+ }
+
+ class Program
+ {
+ static unsafe int Main(string[] args)
+ {
+ bool value = true;
+ NonBlittablePointerNative.Negate(&value);
+ return value == false ? 100 : 101;
+ }
+ }
+}