diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj
index acb1d91dae2d82..9ebc831152ff28 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj
+++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj
@@ -141,7 +141,6 @@
-
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/Common/Variant.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/Common/Variant.cs
deleted file mode 100644
index bc97d99bb052a2..00000000000000
--- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/Common/Variant.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Runtime.InteropServices.Tests.Common
-{
- public struct Variant
- {
-#pragma warning disable 0649
- public ushort vt;
- public ushort wReserved1;
- public ushort wReserved2;
- public ushort wReserved3;
- public IntPtr bstrVal;
- public IntPtr pRecInfo;
-#pragma warning restore 0649
- }
-}
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/GetNativeVariantForObjectTests.Windows.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/GetNativeVariantForObjectTests.Windows.cs
index ea466ac7d31767..0b6737a8326307 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/GetNativeVariantForObjectTests.Windows.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/GetNativeVariantForObjectTests.Windows.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
+using System.Runtime.InteropServices.Marshalling;
using System.Runtime.InteropServices.Tests.Common;
using Xunit;
@@ -108,8 +109,7 @@ public static IEnumerable GetNativeVariantForObject_InvalidArrayType_T
[MemberData(nameof(GetNativeVariantForObject_InvalidArrayType_TestData))]
public void GetNativeVariantForObject_InvalidArrayType_ThrowsInvalidCastException(object obj)
{
- Variant v = new Variant();
- IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf(v));
+ IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf());
try
{
Assert.Throws(() => Marshal.GetNativeVariantForObject(obj, pNative));
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/GetNativeVariantForObjectTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/GetNativeVariantForObjectTests.cs
index 108a842a3c8b39..5c0eac01f22750 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/GetNativeVariantForObjectTests.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/GetNativeVariantForObjectTests.cs
@@ -5,6 +5,7 @@
using System.Drawing;
using System.Reflection;
using System.Reflection.Emit;
+using System.Runtime.InteropServices.Marshalling;
using System.Runtime.InteropServices.Tests.Common;
using Xunit;
@@ -107,32 +108,35 @@ public static IEnumerable GetNativeVariantForObject_NonRoundtrippingPr
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltInComEnabled))]
[MemberData(nameof(GetNativeVariantForObject_NonRoundtrippingPrimitives_TestData))]
- public void GetNativeVariantForObject_ValidObject_Success(object primitive, VarEnum expectedVarType, IntPtr expectedValue, object expectedRoundtripValue)
+ public unsafe void GetNativeVariantForObject_ValidObject_Success(object primitive, VarEnum expectedVarType, IntPtr expectedValue, object expectedRoundtripValue)
{
- var v = new Variant();
- IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf(v));
+ ComVariant variant = default;
+ bool variantInitialized = false;
try
{
- Marshal.GetNativeVariantForObject(primitive, pNative);
+ Marshal.GetNativeVariantForObject(primitive, (nint)(&variant));
+ variantInitialized = true;
- Variant result = Marshal.PtrToStructure(pNative);
- Assert.Equal(expectedVarType, (VarEnum)result.vt);
+ Assert.Equal(expectedVarType, variant.VarType);
if (expectedValue != (IntPtr)(-1))
{
- Assert.Equal(expectedValue, result.bstrVal);
+ Assert.Equal(expectedValue, variant.GetRawDataRef());
}
else
{
- Assert.NotEqual((IntPtr)(-1), result.bstrVal);
- Assert.NotEqual(IntPtr.Zero, result.bstrVal);
+ Assert.NotEqual((IntPtr)(-1), variant.GetRawDataRef());
+ Assert.NotEqual(IntPtr.Zero, variant.GetRawDataRef());
}
// Make sure it roundtrips.
- Assert.Equal(expectedRoundtripValue, Marshal.GetObjectForNativeVariant(pNative));
+ Assert.Equal(expectedRoundtripValue, Marshal.GetObjectForNativeVariant((nint)(&variant)));
}
finally
{
- Marshal.FreeHGlobal(pNative);
+ if (variantInitialized)
+ {
+ variant.Dispose();
+ }
}
}
@@ -141,24 +145,23 @@ public void GetNativeVariantForObject_ValidObject_Success(object primitive, VarE
[InlineData("99")]
public void GetNativeVariantForObject_String_Success(string obj)
{
- var v = new Variant();
- IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf(v));
+ IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf());
try
{
Marshal.GetNativeVariantForObject(obj, pNative);
- Variant result = Marshal.PtrToStructure(pNative);
+ ComVariant result = Marshal.PtrToStructure(pNative);
try
{
- Assert.Equal(VarEnum.VT_BSTR, (VarEnum)result.vt);
- Assert.Equal(obj, Marshal.PtrToStringBSTR(result.bstrVal));
+ Assert.Equal(VarEnum.VT_BSTR, result.VarType);
+ Assert.Equal(obj, Marshal.PtrToStringBSTR(result.GetRawDataRef()));
object o = Marshal.GetObjectForNativeVariant(pNative);
Assert.Equal(obj, o);
}
finally
{
- Marshal.FreeBSTR(result.bstrVal);
+ Marshal.FreeBSTR(result.GetRawDataRef());
}
}
finally
@@ -171,8 +174,7 @@ public void GetNativeVariantForObject_String_Success(string obj)
public unsafe void GetNativeVariantForObject_Guid_Success()
{
var guid = new Guid("0DD3E51B-3162-4D13-B906-030F402C5BA2");
- var v = new Variant();
- IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf(v));
+ IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf());
try
{
if (PlatformDetection.IsWindowsNanoServer)
@@ -183,12 +185,12 @@ public unsafe void GetNativeVariantForObject_Guid_Success()
{
Marshal.GetNativeVariantForObject(guid, pNative);
- Variant result = Marshal.PtrToStructure(pNative);
- Assert.Equal(VarEnum.VT_RECORD, (VarEnum)result.vt);
- Assert.NotEqual(nint.Zero, result.pRecInfo); // We should have an IRecordInfo instance.
+ ComVariant result = Marshal.PtrToStructure(pNative);
+ Assert.Equal(VarEnum.VT_RECORD, result.VarType);
+ Assert.NotEqual(nint.Zero, result.GetRawDataRef()._recordInfo); // We should have an IRecordInfo instance.
var expectedBytes = new ReadOnlySpan(guid.ToByteArray());
- var actualBytes = new ReadOnlySpan((void*)result.bstrVal, expectedBytes.Length);
+ var actualBytes = new ReadOnlySpan((void*)result.GetRawDataRef()._record, expectedBytes.Length);
Assert.Equal(expectedBytes, actualBytes);
object o = Marshal.GetObjectForNativeVariant(pNative);
@@ -205,15 +207,14 @@ public unsafe void GetNativeVariantForObject_Guid_Success()
[InlineData(3.14)]
public unsafe void GetNativeVariantForObject_Double_Success(double obj)
{
- var v = new Variant();
- IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf(v));
+ IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf());
try
{
Marshal.GetNativeVariantForObject(obj, pNative);
- Variant result = Marshal.PtrToStructure(pNative);
- Assert.Equal(VarEnum.VT_R8, (VarEnum)result.vt);
- Assert.Equal(*((ulong*)&obj), *((ulong*)&result.bstrVal));
+ ComVariant result = Marshal.PtrToStructure(pNative);
+ Assert.Equal(VarEnum.VT_R8, result.VarType);
+ Assert.Equal(*((ulong*)&obj), result.GetRawDataRef());
object o = Marshal.GetObjectForNativeVariant(pNative);
Assert.Equal(obj, o);
@@ -228,15 +229,14 @@ public unsafe void GetNativeVariantForObject_Double_Success(double obj)
[InlineData(3.14f)]
public unsafe void GetNativeVariantForObject_Float_Success(float obj)
{
- var v = new Variant();
- IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf(v));
+ IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf());
try
{
Marshal.GetNativeVariantForObject(obj, pNative);
- Variant result = Marshal.PtrToStructure(pNative);
- Assert.Equal(VarEnum.VT_R4, (VarEnum)result.vt);
- Assert.Equal(*((uint*)&obj), *((uint*)&result.bstrVal));
+ ComVariant result = Marshal.PtrToStructure(pNative);
+ Assert.Equal(VarEnum.VT_R4, result.VarType);
+ Assert.Equal(*((uint*)&obj), result.GetRawDataRef());
object o = Marshal.GetObjectForNativeVariant(pNative);
Assert.Equal(obj, o);
@@ -279,8 +279,7 @@ public void GetNativeVariantForObject_GenericObject_ThrowsArgumentException(obje
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltInComEnabled))]
public void GetNativeVariant_InvalidArray_ThrowsSafeArrayTypeMismatchException()
{
- var v = new Variant();
- IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf(v));
+ IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf());
try
{
Assert.Throws(() => Marshal.GetNativeVariantForObject(new int[][] { }, pNative));
@@ -302,8 +301,7 @@ public static IEnumerable GetNativeVariant_VariantWrapper_TestData()
[MemberData(nameof(GetNativeVariant_VariantWrapper_TestData))]
public void GetNativeVariant_VariantWrapper_ThrowsArgumentException(object obj)
{
- var v = new Variant();
- IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf(v));
+ IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf());
try
{
AssertExtensions.Throws(null, () => Marshal.GetNativeVariantForObject(obj, pNative));
@@ -328,8 +326,7 @@ public static IEnumerable GetNativeVariant_HandleObject_TestData()
[MemberData(nameof(GetNativeVariant_HandleObject_TestData))]
public void GetNativeVariant_HandleObject_ThrowsArgumentException(object obj)
{
- var v = new Variant();
- IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf(v));
+ IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf());
try
{
AssertExtensions.Throws(null, () => Marshal.GetNativeVariantForObject(obj, pNative));
@@ -346,8 +343,7 @@ public static void GetNativeVariantForObject_CantCastToObject_ThrowsInvalidCastE
{
// While GetNativeVariantForObject supports taking chars, GetObjectForNativeVariant will
// never return a char. The internal type is ushort, as mentioned above.
- var v = new Variant();
- IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf(v));
+ IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf());
try
{
Marshal.GetNativeVariantForObject('a', pNative);
@@ -372,6 +368,13 @@ public enum UInt16Enum : ushort { Value1, Value2 }
public enum UInt32Enum : uint { Value1, Value2 }
public enum UInt64Enum : ulong { Value1, Value2 }
+ [StructLayout(LayoutKind.Sequential)]
+ private struct Record
+ {
+ public nint _record;
+ public nint _recordInfo;
+ }
+
public class FakeSafeHandle : SafeHandle
{
public FakeSafeHandle() : base(IntPtr.Zero, false) { }