diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index b25afff5a6fda..32215a3e69235 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -560,6 +560,35 @@ bool Compiler::isTrivialPointerSizedStruct(CORINFO_CLASS_HANDLE clsHnd) const } #endif // TARGET_X86 +//--------------------------------------------------------------------------- +// isNativePrimitiveStructType: +// Check if the given struct type is an intrinsic type that should be treated as though +// it is not a struct at the unmanaged ABI boundary. +// +// Arguments: +// clsHnd - the handle for the struct type. +// +// Return Value: +// true if the given struct type should be treated as a primitive for unmanaged calls, +// false otherwise. +// +bool Compiler::isNativePrimitiveStructType(CORINFO_CLASS_HANDLE clsHnd) +{ + if (!isIntrinsicType(clsHnd)) + { + return false; + } + const char* namespaceName = nullptr; + const char* typeName = getClassNameFromMetadata(clsHnd, &namespaceName); + + if (strcmp(namespaceName, "System.Runtime.InteropServices") != 0) + { + return false; + } + + return strcmp(typeName, "CLong") == 0 || strcmp(typeName, "CULong") == 0 || strcmp(typeName, "NFloat") == 0; +} + //----------------------------------------------------------------------------- // getPrimitiveTypeForStruct: // Get the "primitive" type that is is used for a struct @@ -1013,14 +1042,14 @@ var_types Compiler::getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd, } } #elif UNIX_X86_ABI - if (callConv != CorInfoCallConvExtension::Managed) + if (callConv != CorInfoCallConvExtension::Managed && !isNativePrimitiveStructType(clsHnd)) { canReturnInRegister = false; howToReturnStruct = SPK_ByReference; useType = TYP_UNKNOWN; } #elif defined(TARGET_WINDOWS) && !defined(TARGET_ARM) - if (callConvIsInstanceMethodCallConv(callConv)) + if (callConvIsInstanceMethodCallConv(callConv) && !isNativePrimitiveStructType(clsHnd)) { canReturnInRegister = false; howToReturnStruct = SPK_ByReference; diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 1cdebfb9c3c8a..cbbce784bbd06 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -5046,6 +5046,10 @@ class Compiler // Convert a BYTE which represents the VM's CorInfoGCtype to the JIT's var_types var_types getJitGCType(BYTE gcType); + // Returns true if the provided type should be treated as a primitive type + // for the unmanaged calling conventions. + bool isNativePrimitiveStructType(CORINFO_CLASS_HANDLE clsHnd); + enum structPassingKind { SPK_Unknown, // Invalid value, never returned @@ -8045,6 +8049,21 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #endif } + bool isIntrinsicType(CORINFO_CLASS_HANDLE clsHnd) + { + return info.compCompHnd->isIntrinsicType(clsHnd); + } + + const char* getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName) + { + return info.compCompHnd->getClassNameFromMetadata(cls, namespaceName); + } + + CORINFO_CLASS_HANDLE getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index) + { + return info.compCompHnd->getTypeInstantiationArgument(cls, index); + } + #ifdef FEATURE_SIMD // Should we support SIMD intrinsics? @@ -8263,21 +8282,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX return false; } - bool isIntrinsicType(CORINFO_CLASS_HANDLE clsHnd) - { - return info.compCompHnd->isIntrinsicType(clsHnd); - } - - const char* getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName) - { - return info.compCompHnd->getClassNameFromMetadata(cls, namespaceName); - } - - CORINFO_CLASS_HANDLE getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index) - { - return info.compCompHnd->getTypeInstantiationArgument(cls, index); - } - bool isSIMDClass(typeInfo* pTypeInfo) { return pTypeInfo->IsStruct() && isSIMDClass(pTypeInfo->GetClassHandleForValueClass()); diff --git a/src/coreclr/vm/dllimportcallback.cpp b/src/coreclr/vm/dllimportcallback.cpp index 1a50a5e7c9898..337876d7b9257 100644 --- a/src/coreclr/vm/dllimportcallback.cpp +++ b/src/coreclr/vm/dllimportcallback.cpp @@ -178,7 +178,7 @@ VOID UMEntryThunk::CompileUMThunkWorker(UMThunkStubInfo *pInfo, // push edx - repush the return address pcpusl->X86EmitPushReg(kEDX); } - + // The native signature doesn't have a return buffer // but the managed signature does. // Set up the return buffer address here. @@ -188,12 +188,12 @@ VOID UMEntryThunk::CompileUMThunkWorker(UMThunkStubInfo *pInfo, // Calculate the offset to the return buffer we establish for EAX:EDX below. // lea edx [esp - offset to EAX:EDX return buffer] pcpusl->X86EmitEspOffset(0x8d, kEDX, -0xc /* skip return addr, EBP, EBX */ -0x8 /* point to start of EAX:EDX return buffer */ ); - + // exchange edx (which has the return buffer address) // with the return address // xchg edx, [esp] - pcpusl->X86EmitOp(0x87, kEDX, (X86Reg)kESP_Unsafe); - + pcpusl->X86EmitOp(0x87, kEDX, (X86Reg)kESP_Unsafe); + // push edx pcpusl->X86EmitPushReg(kEDX); } @@ -497,7 +497,7 @@ VOID UMEntryThunk::CompileUMThunkWorker(UMThunkStubInfo *pInfo, pcpusl->X86EmitIndexRegStore(kEBX, -0x8 /* to outer EBP */ -0x8 /* skip saved EBP, EBX */, kEDX); } // In the umtmlBufRetValToEnreg case, - // we set up the return buffer to output + // we set up the return buffer to output // into the EDX:EAX buffer we set up for the register return case. // So we don't need to do more work here. else if ((pInfo->m_wFlags & umtmlBufRetValToEnreg) == 0) @@ -684,7 +684,7 @@ Stub *UMThunkMarshInfo::CompileNExportThunk(LoaderHeap *pLoaderHeap, PInvokeStat UINT nOffset = 0; int numRegistersUsed = 0; int numStackSlotsIndex = nStackBytes / STACK_ELEM_SIZE; - + // This could have been set in the UnmanagedCallersOnly scenario. if (m_callConv == UINT16_MAX) m_callConv = static_cast(pSigInfo->GetCallConv()); @@ -699,8 +699,30 @@ Stub *UMThunkMarshInfo::CompileNExportThunk(LoaderHeap *pLoaderHeap, PInvokeStat numRegistersUsed++; } + bool hasReturnBuffer = argit.HasRetBuffArg() || (m_callConv == pmCallConvThiscall && argit.HasValueTypeReturn()); + bool hasNativeExchangeTypeReturn = false; + + if (hasReturnBuffer) + { + // If think we have a return buffer, lets make sure that we aren't returning one of the intrinsic native exchange types. + TypeHandle returnType = pMetaSig->GetRetTypeHandleThrowing(); + if (returnType.GetMethodTable()->IsIntrinsicType()) + { + LPCUTF8 pszNamespace; + LPCUTF8 pszTypeName = returnType.GetMethodTable()->GetFullyQualifiedNameInfo(&pszNamespace); + if ((strcmp(pszNamespace, g_InteropServicesNS) == 0) + && (strcmp(pszTypeName, "CLong") == 0 || strcmp(pszTypeName, "CULong") == 0 || strcmp(pszTypeName, "NFloat") == 0)) + { + // We have one of the intrinsic native exchange types. + // As a result, we don't have a return buffer. + hasReturnBuffer = false; + hasNativeExchangeTypeReturn = true; + } + } + } + // process the return buffer parameter - if (argit.HasRetBuffArg() || (m_callConv == pmCallConvThiscall && argit.HasValueTypeReturn())) + if (hasReturnBuffer) { // Only copy the retbuf arg from the src call when both the managed call and native call // have a return buffer. @@ -808,7 +830,7 @@ Stub *UMThunkMarshInfo::CompileNExportThunk(LoaderHeap *pLoaderHeap, PInvokeStat { stubInfo.m_wFlags |= umtmlThisCallHiddenArg; } - else if (argit.HasValueTypeReturn()) + else if (argit.HasValueTypeReturn() && !hasNativeExchangeTypeReturn) { stubInfo.m_wFlags |= umtmlThisCallHiddenArg | umtmlEnregRetValToBuf; // When the native signature has a return buffer but the diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index b4520cc674845..53b02129328bf 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -43,6 +43,7 @@ public static partial class PlatformDetection public static bool IsArgIteratorSupported => IsMonoRuntime || (IsWindows && IsNotArmProcess); public static bool IsArgIteratorNotSupported => !IsArgIteratorSupported; public static bool Is32BitProcess => IntPtr.Size == 4; + public static bool Is64BitProcess => IntPtr.Size == 8; public static bool IsNotWindows => !IsWindows; public static bool IsThreadingSupported => !IsBrowser; diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index af8dac2c31374..6646fd0a281de 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -707,6 +707,7 @@ + @@ -735,6 +736,7 @@ + @@ -769,6 +771,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CLong.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CLong.cs new file mode 100644 index 0000000000000..3d4e868c6b766 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CLong.cs @@ -0,0 +1,78 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; + +#pragma warning disable SA1121 // We use our own aliases since they differ per platform +#if TARGET_WINDOWS +using NativeType = System.Int32; +#else +using NativeType = System.IntPtr; +#endif + +namespace System.Runtime.InteropServices +{ + /// + /// is an immutable value type that represents the long type in C and C++. + /// It is meant to be used as an exchange type at the managed/unmanaged boundary to accurately represent + /// in managed code unmanaged APIs that use the long type. + /// This type has 32-bits of storage on all Windows platforms and 32-bit Unix-based platforms. + /// It has 64-bits of storage on 64-bit Unix platforms. + /// + [CLSCompliant(false)] + [Intrinsic] + public readonly struct CLong : IEquatable + { + private readonly NativeType _value; + + /// + /// Constructs an instance from a 32-bit integer. + /// + /// The integer vaule. + public CLong(int value) + { + _value = (NativeType)value; + } + + /// + /// Constructs an instance from a native sized integer. + /// + /// The integer vaule. + /// is outside the range of the underlying storage type. + public CLong(nint value) + { + _value = checked((NativeType)value); + } + + /// + /// The underlying integer value of this instance. + /// + public nint Value => _value; + + /// + /// Returns a value indicating whether this instance is equal to a specified object. + /// + /// An object to compare with this instance. + /// true if is an instance of and equals the value of this instance; otherwise, false. + public override bool Equals(object? o) => o is CLong other && Equals(other); + + /// + /// Returns a value indicating whether this instance is equal to a specified value. + /// + /// A value to compare to this instance. + /// true if has the same value as this instance; otherwise, false. + public bool Equals(CLong other) => _value == other._value; + + /// + /// Returns the hash code for this instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() => _value.GetHashCode(); + + /// + /// Converts the numeric value of this instance to its equivalent string representation. + /// + /// The string representation of the value of this instance, consisting of a negative sign if the value is negative, and a sequence of digits ranging from 0 to 9 with no leading zeroes. + public override string ToString() => _value.ToString(); + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CULong.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CULong.cs new file mode 100644 index 0000000000000..8ad64727e92bb --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CULong.cs @@ -0,0 +1,78 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; + +#pragma warning disable SA1121 // We use our own aliases since they differ per platform +#if TARGET_WINDOWS +using NativeType = System.UInt32; +#else +using NativeType = System.UIntPtr; +#endif + +namespace System.Runtime.InteropServices +{ + /// + /// is an immutable value type that represents the unsigned long type in C and C++. + /// It is meant to be used as an exchange type at the managed/unmanaged boundary to accurately represent + /// in managed code unmanaged APIs that use the unsigned long type. + /// This type has 32-bits of storage on all Windows platforms and 32-bit Unix-based platforms. + /// It has 64-bits of storage on 64-bit Unix platforms. + /// + [CLSCompliant(false)] + [Intrinsic] + public readonly struct CULong : IEquatable + { + private readonly NativeType _value; + + /// + /// Constructs an instance from a 32-bit unsigned integer. + /// + /// The integer vaule. + public CULong(uint value) + { + _value = (NativeType)value; + } + + /// + /// Constructs an instance from a native sized unsigned integer. + /// + /// The integer vaule. + /// is outside the range of the underlying storage type. + public CULong(nuint value) + { + _value = checked((NativeType)value); + } + + /// + /// The underlying integer value of this instance. + /// + public nuint Value => _value; + + /// + /// Returns a value indicating whether this instance is equal to a specified object. + /// + /// An object to compare with this instance. + /// true if is an instance of and equals the value of this instance; otherwise, false. + public override bool Equals(object? o) => o is CULong other && Equals(other); + + /// + /// Returns a value indicating whether this instance is equal to a specified value. + /// + /// A value to compare to this instance. + /// true if has the same value as this instance; otherwise, false. + public bool Equals(CULong other) => _value == other._value; + + /// + /// Returns the hash code for this instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() => _value.GetHashCode(); + + /// + /// Converts the numeric value of this instance to its equivalent string representation. + /// + /// The string representation of the value of this instance, consisting of a sequence of digits ranging from 0 to 9 with no leading zeroes. + public override string ToString() => _value.ToString(); + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs new file mode 100644 index 0000000000000..468d3e55ed5df --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs @@ -0,0 +1,76 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; + +#pragma warning disable SA1121 // We use our own aliases since they differ per platform +#if TARGET_32BIT +using NativeType = System.Single; +#else +using NativeType = System.Double; +#endif + +namespace System.Runtime.InteropServices +{ + /// + /// is an immutable value type that represents a floating type that has the same size + /// as the native integer size. + /// It is meant to be used as an exchange type at the managed/unmanaged boundary to accurately represent + /// in managed code unmanaged APIs that use a type alias for C or C++'s float on 32-bit platforms + /// or double on 64-bit platforms, such as the CGFloat type in libraries provided by Apple. + /// + [Intrinsic] + public readonly struct NFloat : IEquatable + { + private readonly NativeType _value; + + /// + /// Constructs an instance from a 32-bit floating point value. + /// + /// The floating-point vaule. + public NFloat(float value) + { + _value = value; + } + + /// + /// Constructs an instance from a 64-bit floating point value. + /// + /// The floating-point vaule. + public NFloat(double value) + { + _value = (NativeType)value; + } + + /// + /// The underlying floating-point value of this instance. + /// + public double Value => _value; + + /// + /// Returns a value indicating whether this instance is equal to a specified object. + /// + /// An object to compare with this instance. + /// true if is an instance of and equals the value of this instance; otherwise, false. + public override bool Equals(object? o) => o is NFloat other && Equals(other); + + /// + /// Returns a value indicating whether this instance is equal to a specified value. + /// + /// An value to compare to this instance. + /// true if has the same value as this instance; otherwise, false. + public bool Equals(NFloat other) => _value.Equals(other._value); + + /// + /// Returns the hash code for this instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() => _value.GetHashCode(); + + /// + /// Converts the numeric value of this instance to its equivalent string representation. + /// + /// The string representation of the value of this instance. + public override string ToString() => _value.ToString(); + } +} diff --git a/src/libraries/System.Runtime.InteropServices/System.Runtime.InteropServices.sln b/src/libraries/System.Runtime.InteropServices/System.Runtime.InteropServices.sln index 7400e16352b4f..5c2bde08c0163 100644 --- a/src/libraries/System.Runtime.InteropServices/System.Runtime.InteropServices.sln +++ b/src/libraries/System.Runtime.InteropServices/System.Runtime.InteropServices.sln @@ -1,4 +1,8 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30802.240 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", "..\..\coreclr\System.Private.CoreLib\System.Private.CoreLib.csproj", "{94B59BA0-491F-4B59-ADFF-A057EC3EC835}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}" @@ -7,7 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Win32.Registry", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{5BB5F99F-1052-4EB4-B12E-7863805661F3}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\src\System.Runtime.CompilerServices.Unsafe.ilproj", "{23735A0B-AB51-4C1D-BD88-5240D672DD33}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\src\System.Runtime.CompilerServices.Unsafe.ilproj", "{04BA3E3C-6979-4792-B19E-C797AD607F42}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.InteropServices", "ref\System.Runtime.InteropServices.csproj", "{8671F164-F78C-44FA-93B7-A310F67890FE}" EndProject @@ -26,30 +30,27 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{E7481FAF-728B-448D-9A38-88B40E3C400E}" EndProject Global - GlobalSection(NestedProjects) = preSolution - {94B59BA0-491F-4B59-ADFF-A057EC3EC835} = {F66D19A6-4D11-45EC-B73F-7F4E4F8DB76B} - {23735A0B-AB51-4C1D-BD88-5240D672DD33} = {F66D19A6-4D11-45EC-B73F-7F4E4F8DB76B} - {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1} = {F66D19A6-4D11-45EC-B73F-7F4E4F8DB76B} - {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA} = {451A41C1-B1BC-49DE-8F3F-26F2D8BF841A} - {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664} = {451A41C1-B1BC-49DE-8F3F-26F2D8BF841A} - {EB306595-C964-474F-AFEE-803C886E4B8B} = {E7481FAF-728B-448D-9A38-88B40E3C400E} - {5BB5F99F-1052-4EB4-B12E-7863805661F3} = {E7481FAF-728B-448D-9A38-88B40E3C400E} - {8671F164-F78C-44FA-93B7-A310F67890FE} = {E7481FAF-728B-448D-9A38-88B40E3C400E} - {B8C46FFD-86D0-4C84-97A5-60DDF29ED543} = {E7481FAF-728B-448D-9A38-88B40E3C400E} - {92B81157-BB47-4A19-9229-23AE9B126DAA} = {E7481FAF-728B-448D-9A38-88B40E3C400E} + GlobalSection(SharedMSBuildProjectFiles) = preSolution + ..\System.Private.CoreLib\src\System.Private.CoreLib.Shared.projitems*{94b59ba0-491f-4b59-adff-a057ec3ec835}*SharedItemsImports = 5 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution + Checked|Any CPU = Checked|Any CPU + Checked|x64 = Checked|x64 + Checked|x86 = Checked|x86 Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 - Checked|Any CPU = Checked|Any CPU - Checked|x64 = Checked|x64 - Checked|x86 = Checked|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|Any CPU.ActiveCfg = Checked|x64 + {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|Any CPU.Build.0 = Checked|x64 + {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x64.ActiveCfg = Checked|x64 + {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x64.Build.0 = Checked|x64 + {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x86.ActiveCfg = Checked|x86 + {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x86.Build.0 = Checked|x86 {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Debug|Any CPU.ActiveCfg = Debug|x64 {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Debug|Any CPU.Build.0 = Debug|x64 {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Debug|x64.ActiveCfg = Debug|x64 @@ -62,12 +63,9 @@ Global {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Release|x64.Build.0 = Release|x64 {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Release|x86.ActiveCfg = Release|x86 {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Release|x86.Build.0 = Release|x86 - {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|Any CPU.ActiveCfg = Checked|x64 - {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|Any CPU.Build.0 = Checked|x64 - {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x64.ActiveCfg = Checked|x64 - {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x64.Build.0 = Checked|x64 - {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x86.ActiveCfg = Checked|x86 - {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x86.Build.0 = Checked|x86 + {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|x64.ActiveCfg = Debug|Any CPU + {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|x86.ActiveCfg = Debug|Any CPU {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Debug|Any CPU.Build.0 = Debug|Any CPU {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -80,9 +78,9 @@ Global {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Release|x64.Build.0 = Release|Any CPU {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Release|x86.ActiveCfg = Release|Any CPU {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Release|x86.Build.0 = Release|Any CPU - {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|x64.ActiveCfg = Debug|Any CPU - {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|x86.ActiveCfg = Debug|Any CPU + {EB306595-C964-474F-AFEE-803C886E4B8B}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {EB306595-C964-474F-AFEE-803C886E4B8B}.Checked|x64.ActiveCfg = Debug|Any CPU + {EB306595-C964-474F-AFEE-803C886E4B8B}.Checked|x86.ActiveCfg = Debug|Any CPU {EB306595-C964-474F-AFEE-803C886E4B8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EB306595-C964-474F-AFEE-803C886E4B8B}.Debug|Any CPU.Build.0 = Debug|Any CPU {EB306595-C964-474F-AFEE-803C886E4B8B}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -95,9 +93,9 @@ Global {EB306595-C964-474F-AFEE-803C886E4B8B}.Release|x64.Build.0 = Release|Any CPU {EB306595-C964-474F-AFEE-803C886E4B8B}.Release|x86.ActiveCfg = Release|Any CPU {EB306595-C964-474F-AFEE-803C886E4B8B}.Release|x86.Build.0 = Release|Any CPU - {EB306595-C964-474F-AFEE-803C886E4B8B}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {EB306595-C964-474F-AFEE-803C886E4B8B}.Checked|x64.ActiveCfg = Debug|Any CPU - {EB306595-C964-474F-AFEE-803C886E4B8B}.Checked|x86.ActiveCfg = Debug|Any CPU + {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|x64.ActiveCfg = Debug|Any CPU + {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|x86.ActiveCfg = Debug|Any CPU {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Debug|Any CPU.Build.0 = Debug|Any CPU {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -110,24 +108,24 @@ Global {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Release|x64.Build.0 = Release|Any CPU {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Release|x86.ActiveCfg = Release|Any CPU {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Release|x86.Build.0 = Release|Any CPU - {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|x64.ActiveCfg = Debug|Any CPU - {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|x86.ActiveCfg = Debug|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Debug|Any CPU.Build.0 = Debug|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Debug|x64.ActiveCfg = Debug|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Debug|x64.Build.0 = Debug|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Debug|x86.ActiveCfg = Debug|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Debug|x86.Build.0 = Debug|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Release|Any CPU.ActiveCfg = Release|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Release|Any CPU.Build.0 = Release|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Release|x64.ActiveCfg = Release|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Release|x64.Build.0 = Release|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Release|x86.ActiveCfg = Release|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Release|x86.Build.0 = Release|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Checked|x64.ActiveCfg = Debug|Any CPU - {23735A0B-AB51-4C1D-BD88-5240D672DD33}.Checked|x86.ActiveCfg = Debug|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|x64.ActiveCfg = Debug|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|x86.ActiveCfg = Debug|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Debug|Any CPU.Build.0 = Debug|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Debug|x64.ActiveCfg = Debug|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Debug|x64.Build.0 = Debug|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Debug|x86.ActiveCfg = Debug|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Debug|x86.Build.0 = Debug|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Release|Any CPU.ActiveCfg = Release|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Release|Any CPU.Build.0 = Release|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Release|x64.ActiveCfg = Release|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Release|x64.Build.0 = Release|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Release|x86.ActiveCfg = Release|Any CPU + {04BA3E3C-6979-4792-B19E-C797AD607F42}.Release|x86.Build.0 = Release|Any CPU + {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|x64.ActiveCfg = Debug|Any CPU + {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|x86.ActiveCfg = Debug|Any CPU {8671F164-F78C-44FA-93B7-A310F67890FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8671F164-F78C-44FA-93B7-A310F67890FE}.Debug|Any CPU.Build.0 = Debug|Any CPU {8671F164-F78C-44FA-93B7-A310F67890FE}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -140,9 +138,9 @@ Global {8671F164-F78C-44FA-93B7-A310F67890FE}.Release|x64.Build.0 = Release|Any CPU {8671F164-F78C-44FA-93B7-A310F67890FE}.Release|x86.ActiveCfg = Release|Any CPU {8671F164-F78C-44FA-93B7-A310F67890FE}.Release|x86.Build.0 = Release|Any CPU - {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|x64.ActiveCfg = Debug|Any CPU - {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|x86.ActiveCfg = Debug|Any CPU + {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|x64.ActiveCfg = Debug|Any CPU + {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|x86.ActiveCfg = Debug|Any CPU {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Debug|Any CPU.Build.0 = Debug|Any CPU {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -155,9 +153,9 @@ Global {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Release|x64.Build.0 = Release|Any CPU {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Release|x86.ActiveCfg = Release|Any CPU {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Release|x86.Build.0 = Release|Any CPU - {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|x64.ActiveCfg = Debug|Any CPU - {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|x86.ActiveCfg = Debug|Any CPU + {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664}.Checked|x64.ActiveCfg = Debug|Any CPU + {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664}.Checked|x86.ActiveCfg = Debug|Any CPU {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664}.Debug|Any CPU.Build.0 = Debug|Any CPU {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -170,9 +168,9 @@ Global {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664}.Release|x64.Build.0 = Release|Any CPU {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664}.Release|x86.ActiveCfg = Release|Any CPU {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664}.Release|x86.Build.0 = Release|Any CPU - {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664}.Checked|x64.ActiveCfg = Debug|Any CPU - {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664}.Checked|x86.ActiveCfg = Debug|Any CPU + {B8C46FFD-86D0-4C84-97A5-60DDF29ED543}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {B8C46FFD-86D0-4C84-97A5-60DDF29ED543}.Checked|x64.ActiveCfg = Debug|Any CPU + {B8C46FFD-86D0-4C84-97A5-60DDF29ED543}.Checked|x86.ActiveCfg = Debug|Any CPU {B8C46FFD-86D0-4C84-97A5-60DDF29ED543}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B8C46FFD-86D0-4C84-97A5-60DDF29ED543}.Debug|Any CPU.Build.0 = Debug|Any CPU {B8C46FFD-86D0-4C84-97A5-60DDF29ED543}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -185,9 +183,9 @@ Global {B8C46FFD-86D0-4C84-97A5-60DDF29ED543}.Release|x64.Build.0 = Release|Any CPU {B8C46FFD-86D0-4C84-97A5-60DDF29ED543}.Release|x86.ActiveCfg = Release|Any CPU {B8C46FFD-86D0-4C84-97A5-60DDF29ED543}.Release|x86.Build.0 = Release|Any CPU - {B8C46FFD-86D0-4C84-97A5-60DDF29ED543}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {B8C46FFD-86D0-4C84-97A5-60DDF29ED543}.Checked|x64.ActiveCfg = Debug|Any CPU - {B8C46FFD-86D0-4C84-97A5-60DDF29ED543}.Checked|x86.ActiveCfg = Debug|Any CPU + {92B81157-BB47-4A19-9229-23AE9B126DAA}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {92B81157-BB47-4A19-9229-23AE9B126DAA}.Checked|x64.ActiveCfg = Debug|Any CPU + {92B81157-BB47-4A19-9229-23AE9B126DAA}.Checked|x86.ActiveCfg = Debug|Any CPU {92B81157-BB47-4A19-9229-23AE9B126DAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {92B81157-BB47-4A19-9229-23AE9B126DAA}.Debug|Any CPU.Build.0 = Debug|Any CPU {92B81157-BB47-4A19-9229-23AE9B126DAA}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -200,13 +198,22 @@ Global {92B81157-BB47-4A19-9229-23AE9B126DAA}.Release|x64.Build.0 = Release|Any CPU {92B81157-BB47-4A19-9229-23AE9B126DAA}.Release|x86.ActiveCfg = Release|Any CPU {92B81157-BB47-4A19-9229-23AE9B126DAA}.Release|x86.Build.0 = Release|Any CPU - {92B81157-BB47-4A19-9229-23AE9B126DAA}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {92B81157-BB47-4A19-9229-23AE9B126DAA}.Checked|x64.ActiveCfg = Debug|Any CPU - {92B81157-BB47-4A19-9229-23AE9B126DAA}.Checked|x86.ActiveCfg = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {94B59BA0-491F-4B59-ADFF-A057EC3EC835} = {F66D19A6-4D11-45EC-B73F-7F4E4F8DB76B} + {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA} = {451A41C1-B1BC-49DE-8F3F-26F2D8BF841A} + {EB306595-C964-474F-AFEE-803C886E4B8B} = {E7481FAF-728B-448D-9A38-88B40E3C400E} + {5BB5F99F-1052-4EB4-B12E-7863805661F3} = {E7481FAF-728B-448D-9A38-88B40E3C400E} + {04BA3E3C-6979-4792-B19E-C797AD607F42} = {F66D19A6-4D11-45EC-B73F-7F4E4F8DB76B} + {8671F164-F78C-44FA-93B7-A310F67890FE} = {E7481FAF-728B-448D-9A38-88B40E3C400E} + {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1} = {F66D19A6-4D11-45EC-B73F-7F4E4F8DB76B} + {E249BD6A-85DB-4CE4-BD82-8D67EBAC5664} = {451A41C1-B1BC-49DE-8F3F-26F2D8BF841A} + {B8C46FFD-86D0-4C84-97A5-60DDF29ED543} = {E7481FAF-728B-448D-9A38-88B40E3C400E} + {92B81157-BB47-4A19-9229-23AE9B126DAA} = {E7481FAF-728B-448D-9A38-88B40E3C400E} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D4031401-FEB5-4CCF-91C1-38F5646B2BFD} EndGlobalSection diff --git a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs index 7f491686875d3..da17c552dd818 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -156,6 +156,17 @@ public enum ClassInterfaceType [System.ObsoleteAttribute("Support for IDispatch may be unavailable in future releases.")] AutoDual = 2, } + [System.CLSCompliantAttribute(false)] + public readonly struct CLong : IEquatable + { + public CLong(int value) { } + public CLong(nint value) { } + public nint Value { get { throw null; } } + public override bool Equals(object? o) { throw null; } + public bool Equals(CLong other) { throw null; } + public override int GetHashCode() { throw null; } + public override string ToString() { throw null; } + } [System.AttributeUsageAttribute(System.AttributeTargets.Interface, Inherited=false)] public sealed partial class CoClassAttribute : System.Attribute { @@ -280,6 +291,17 @@ public sealed partial class ComUnregisterFunctionAttribute : System.Attribute { public ComUnregisterFunctionAttribute() { } } + [System.CLSCompliantAttribute(false)] + public readonly struct CULong : IEquatable + { + public CULong(uint value) { } + public CULong(nuint value) { } + public nuint Value { get { throw null; } } + public override bool Equals(object? o) { throw null; } + public bool Equals(CULong other) { throw null; } + public override int GetHashCode() { throw null; } + public override string ToString() { throw null; } + } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [System.ObsoleteAttribute("CurrencyWrapper and support for marshalling to the VARIANT type may be unavailable in future releases.")] public sealed partial class CurrencyWrapper @@ -734,6 +756,16 @@ public static void SetDllImportResolver(System.Reflection.Assembly assembly, Sys public static bool TryLoad(string libraryPath, out System.IntPtr handle) { throw null; } public static bool TryLoad(string libraryName, System.Reflection.Assembly assembly, System.Runtime.InteropServices.DllImportSearchPath? searchPath, out System.IntPtr handle) { throw null; } } + public readonly struct NFloat : IEquatable + { + public NFloat(float value) { } + public NFloat(double value) { } + public double Value { get { throw null; } } + public override bool Equals(object? o) { throw null; } + public bool Equals(NFloat other) { throw null; } + public override int GetHashCode() { throw null; } + public override string ToString() { throw null; } + } [System.AttributeUsageAttribute(System.AttributeTargets.Parameter, Inherited=false)] public sealed partial class OptionalAttribute : System.Attribute { diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.Tests.csproj b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.Tests.csproj index 69396c3d0fb95..29c38f3766bfc 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.Tests.csproj @@ -13,6 +13,9 @@ + + + diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/CLongTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/CLongTests.cs new file mode 100644 index 0000000000000..95c05c0f0f37a --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/CLongTests.cs @@ -0,0 +1,103 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace System.Runtime.InteropServices.Tests +{ + public class CLongTests + { + private static bool Has64BitStorage => !Has32BitStorage; + private static bool Has32BitStorage => PlatformDetection.Is32BitProcess || PlatformDetection.IsWindows; + private static bool NativeIntConstructorCanOverflow => !PlatformDetection.Is32BitProcess && Has32BitStorage; + private static bool NativeIntConstructorCannotOverflow => !NativeIntConstructorCanOverflow; + + [Fact] + public void Ctor_Empty() + { + CLong value = new CLong(); + Assert.Equal(0, value.Value); + } + + [Fact] + public void Ctor_Int() + { + CLong value = new CLong(42); + Assert.Equal(42, value.Value); + } + + [Fact] + public void Ctor_NInt() + { + CLong value = new CLong((nint)42); + Assert.Equal(42, value.Value); + } + + [ConditionalFact(nameof(NativeIntConstructorCanOverflow))] + public void Ctor_NInt_OutOfRange() + { + Assert.Throws(() => new CLong(unchecked(((nint)int.MaxValue) + 1))); + } + + [ConditionalFact(nameof(NativeIntConstructorCannotOverflow))] + public void Ctor_NInt_LargeValue() + { + nint largeValue = unchecked(((nint)int.MaxValue) + 1); + CLong value = new CLong(largeValue); + Assert.Equal(largeValue, value.Value); + } + + public static IEnumerable EqualsData() + { + yield return new object[] { new CLong(789), new CLong(789), true }; + yield return new object[] { new CLong(789), new CLong(-789), false }; + yield return new object[] { new CLong(789), new CLong(0), false }; + yield return new object[] { new CLong(0), new CLong(0), true }; + yield return new object[] { new CLong(-789), new CLong(-789), true }; + yield return new object[] { new CLong(-789), new CLong(789), false }; + yield return new object[] { new CLong(789), null, false }; + yield return new object[] { new CLong(789), "789", false }; + yield return new object[] { new CLong(789), 789, false }; + } + + [Theory] + [MemberData(nameof(EqualsData))] + public void EqualsTest(CLong clong, object obj, bool expected) + { + if (obj is CLong clong2) + { + Assert.Equal(expected, clong.Equals(clong2)); + Assert.Equal(expected, clong.GetHashCode().Equals(clong2.GetHashCode())); + } + Assert.Equal(expected, clong.Equals(obj)); + } + + [Theory] + [InlineData(int.MinValue, "-2147483648")] + [InlineData(-4567, "-4567")] + [InlineData(0, "0")] + [InlineData(4567, "4567")] + [InlineData(int.MaxValue, "2147483647")] + public static void ToStringTest(int value, string expected) + { + CLong clong = new CLong(value); + + Assert.Equal(expected, clong.ToString()); + } + + [Fact] + public unsafe void Size() + { + int size = Has32BitStorage ? 4 : 8; +#pragma warning disable xUnit2000 // The value under test here is the sizeof expression + Assert.Equal(size, sizeof(CLong)); +#pragma warning restore xUnit2000 + Assert.Equal(size, Marshal.SizeOf()); + } + } +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/CULongTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/CULongTests.cs new file mode 100644 index 0000000000000..dc1cb30f68cec --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/CULongTests.cs @@ -0,0 +1,99 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace System.Runtime.InteropServices.Tests +{ + public class CULongTests + { + private static bool Has64BitStorage => !Has32BitStorage; + private static bool Has32BitStorage => PlatformDetection.Is32BitProcess || PlatformDetection.IsWindows; + private static bool NativeIntConstructorCanOverflow => !PlatformDetection.Is32BitProcess && Has32BitStorage; + private static bool NativeIntConstructorCannotOverflow => !NativeIntConstructorCanOverflow; + + [Fact] + public void Ctor_Empty() + { + CULong value = new CULong(); + Assert.Equal(0u, value.Value); + } + + [Fact] + public void Ctor_UInt() + { + CULong value = new CULong(42u); + Assert.Equal(42u, value.Value); + } + + [Fact] + public void Ctor_NUInt() + { + CULong value = new CULong((nuint)42); + Assert.Equal(42u, value.Value); + } + + [ConditionalFact(nameof(NativeIntConstructorCanOverflow))] + public void Ctor_NUInt_OutOfRange() + { + Assert.Throws(() => new CULong(unchecked(((nuint)uint.MaxValue) + 1))); + } + + [ConditionalFact(nameof(NativeIntConstructorCannotOverflow))] + public void Ctor_NUInt_LargeValue() + { + nuint largeValue = unchecked(((nuint)uint.MaxValue) + 1); + CULong value = new CULong(largeValue); + Assert.Equal(largeValue, value.Value); + } + + public static IEnumerable EqualsData() + { + yield return new object[] { new CULong(789), new CULong(789), true }; + yield return new object[] { new CULong(789), new CULong(0), false }; + yield return new object[] { new CULong(0), new CULong(0), true }; + yield return new object[] { new CULong(789), null, false }; + yield return new object[] { new CULong(789), "789", false }; + yield return new object[] { new CULong(789), 789u, false }; + } + + [Theory] + [MemberData(nameof(EqualsData))] + public void EqualsTest(CULong culong, object obj, bool expected) + { + if (obj is CULong culong2) + { + Assert.Equal(expected, culong.Equals(culong2)); + Assert.Equal(expected, culong.GetHashCode().Equals(culong2.GetHashCode())); + } + Assert.Equal(expected, culong.Equals(obj)); + } + + + [Theory] + [InlineData(0, "0")] + [InlineData(4567, "4567")] + [InlineData(uint.MaxValue, "4294967295")] + public static void ToStringTest(uint value, string expected) + { + CULong culong = new CULong(value); + + Assert.Equal(expected, culong.ToString()); + } + + [Fact] + public unsafe void Size() + { + int size = Has32BitStorage ? 4 : 8; +#pragma warning disable xUnit2000 // The value under test here is the sizeof expression + Assert.Equal(size, sizeof(CULong)); +#pragma warning restore xUnit2000 + Assert.Equal(size, Marshal.SizeOf()); + } + } +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/NFloatTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/NFloatTests.cs new file mode 100644 index 0000000000000..c2311afae708d --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/NFloatTests.cs @@ -0,0 +1,120 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace System.Runtime.InteropServices.Tests +{ + public class NFloatTests + { + [Fact] + public void Ctor_Empty() + { + NFloat value = new NFloat(); + Assert.Equal(0, value.Value); + } + + [Fact] + public void Ctor_Float() + { + NFloat value = new NFloat(42.0f); + Assert.Equal(42.0, value.Value); + } + + [Fact] + public void Ctor_Double() + { + NFloat value = new NFloat(42.0); + Assert.Equal(42.0, value.Value); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))] + public void Ctor_Double_OutOfRange() + { + NFloat value = new NFloat(double.MaxValue); + Assert.Equal((double)(float)double.MaxValue, value.Value); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] + public void Ctor_Double_LargeValue() + { + NFloat value = new NFloat(double.MaxValue); + Assert.Equal(double.MaxValue, value.Value); + } + + public static IEnumerable EqualsData() + { + yield return new object[] { new NFloat(789.0f), new NFloat(789.0f), true }; + yield return new object[] { new NFloat(789.0f), new NFloat(-789.0f), false }; + yield return new object[] { new NFloat(789.0f), new NFloat(0.0f), false }; + yield return new object[] { new NFloat(789.0f), 789.0f, false }; + yield return new object[] { new NFloat(789.0f), "789.0", false }; + } + + [Theory] + [MemberData(nameof(EqualsData))] + public void EqualsTest(NFloat f1, object obj, bool expected) + { + if (obj is NFloat f2) + { + Assert.Equal(expected, f1.Equals((object)f2)); + Assert.Equal(expected, f1.Equals(f2)); + Assert.Equal(expected, f1.GetHashCode().Equals(f2.GetHashCode())); + } + Assert.Equal(expected, f1.Equals(obj)); + } + + [Fact] + public void NaNEqualsTest() + { + NFloat f1 = new NFloat(float.NaN); + NFloat f2 = new NFloat(float.NaN); + Assert.Equal(f1.Value.Equals(f2.Value), f1.Equals(f2)); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] + [InlineData(-4567.0f)] + [InlineData(-4567.89101f)] + [InlineData(0.0f)] + [InlineData(4567.0f)] + [InlineData(4567.89101f)] + + [InlineData(float.NaN)] + public static void ToStringTest64(float value) + { + NFloat nfloat = new NFloat(value); + + Assert.Equal(((double)value).ToString(), nfloat.ToString()); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))] + [InlineData(-4567.0f)] + [InlineData(-4567.89101f)] + [InlineData(0.0f)] + [InlineData(4567.0f)] + [InlineData(4567.89101f)] + + [InlineData(float.NaN)] + public static void ToStringTest32(float value) + { + NFloat nfloat = new NFloat(value); + + Assert.Equal(value.ToString(), nfloat.ToString()); + } + + [Fact] + public unsafe void Size() + { + int size = PlatformDetection.Is32BitProcess ? 4 : 8; +#pragma warning disable xUnit2000 // The value under test here is the sizeof expression + Assert.Equal(size, sizeof(NFloat)); +#pragma warning restore xUnit2000 + Assert.Equal(size, Marshal.SizeOf()); + } + } +} diff --git a/src/tests/Interop/PInvoke/Miscellaneous/ThisCall/ThisCallNative.cpp b/src/tests/Interop/PInvoke/Miscellaneous/ThisCall/ThisCallNative.cpp index cf2569fb75386..6c70fc5f6de98 100644 --- a/src/tests/Interop/PInvoke/Miscellaneous/ThisCall/ThisCallNative.cpp +++ b/src/tests/Interop/PInvoke/Miscellaneous/ThisCall/ThisCallNative.cpp @@ -57,6 +57,11 @@ class C { return dummy; } + + virtual long GetWidthAsLong() + { + return (long)width; + } }; @@ -84,3 +89,8 @@ extern "C" DLL_EXPORT E STDMETHODCALLTYPE GetEFromManaged(C* c) { return c->GetE(); } + +extern "C" DLL_EXPORT long STDMETHODCALLTYPE GetWidthAsLongFromManaged(C* c) +{ + return c->GetWidthAsLong(); +} diff --git a/src/tests/Interop/PInvoke/Miscellaneous/ThisCall/ThisCallTest.cs b/src/tests/Interop/PInvoke/Miscellaneous/ThisCall/ThisCallTest.cs index 31719e8d7aed8..0509ffe568318 100644 --- a/src/tests/Interop/PInvoke/Miscellaneous/ThisCall/ThisCallTest.cs +++ b/src/tests/Interop/PInvoke/Miscellaneous/ThisCall/ThisCallTest.cs @@ -1,12 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; using System; using System.Reflection; using System.Text; using TestLibrary; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; unsafe class ThisCallNative { @@ -18,6 +18,7 @@ public struct VtableLayout public IntPtr getWidth; public IntPtr getHeightAsInt; public IntPtr getE; + public IntPtr getWidthAsLong; } public VtableLayout* vtable; @@ -57,6 +58,9 @@ public enum E : uint [UnmanagedFunctionPointer(CallingConvention.ThisCall)] public delegate E GetEFn(C* c); + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] + public delegate CLong GetWidthAsLongFn(C* c); + [DllImport(nameof(ThisCallNative))] public static extern C* CreateInstanceOfC(float width, float height); @@ -68,6 +72,8 @@ public enum E : uint public static extern IntWrapper GetHeightAsIntFromManaged(C* c); [DllImport(nameof(ThisCallNative))] public static extern E GetEFromManaged(C* c); + [DllImport(nameof(ThisCallNative))] + public static extern CLong GetWidthAsLongFromManaged(C* c); } unsafe class ThisCallTest @@ -83,14 +89,17 @@ public static int Main(string[] args) Test4ByteHFA(instance); Test4ByteNonHFA(instance); TestEnum(instance); + TestCLong(instance); Test8ByteHFAReverse(); Test4ByteHFAReverse(); Test4ByteNonHFAReverse(); TestEnumReverse(); + TestCLongReverse(); Test8ByteHFAUnmanagedCallersOnly(); Test4ByteHFAUnmanagedCallersOnly(); Test4ByteNonHFAUnmanagedCallersOnly(); TestEnumUnmanagedCallersOnly(); + TestCLongUnmanagedCallersOnly(); } catch (System.Exception ex) { @@ -137,15 +146,24 @@ private static void TestEnum(ThisCallNative.C* instance) Assert.AreEqual(instance->dummy, result); } + private static void TestCLong(ThisCallNative.C* instance) + { + ThisCallNative.GetWidthAsLongFn callback = Marshal.GetDelegateForFunctionPointer(instance->vtable->getWidthAsLong); + + CLong result = callback(instance); + + Assert.AreEqual((nint)instance->width, result.Value); + } + private static void Test8ByteHFAReverse() { ThisCallNative.C c = CreateCWithManagedVTable(2.0f, 3.0f); ThisCallNative.SizeF result = ThisCallNative.GetSizeFromManaged(&c); - + Assert.AreEqual(c.width, result.width); Assert.AreEqual(c.height, result.height); } - + private static void Test4ByteHFAReverse() { ThisCallNative.C c = CreateCWithManagedVTable(2.0f, 3.0f); @@ -169,15 +187,24 @@ private static void TestEnumReverse() Assert.AreEqual(c.dummy, result); } + + private static void TestCLongReverse() + { + ThisCallNative.C c = CreateCWithManagedVTable(2.0f, 3.0f); + CLong result = ThisCallNative.GetWidthAsLongFromManaged(&c); + + Assert.AreEqual((nint)c.width, result.Value); + } + private static void Test8ByteHFAUnmanagedCallersOnly() { ThisCallNative.C c = CreateCWithUnmanagedCallersOnlyVTable(2.0f, 3.0f); ThisCallNative.SizeF result = ThisCallNative.GetSizeFromManaged(&c); - + Assert.AreEqual(c.width, result.width); Assert.AreEqual(c.height, result.height); } - + private static void Test4ByteHFAUnmanagedCallersOnly() { ThisCallNative.C c = CreateCWithUnmanagedCallersOnlyVTable(2.0f, 3.0f); @@ -202,6 +229,14 @@ private static void TestEnumUnmanagedCallersOnly() Assert.AreEqual(c.dummy, result); } + private static void TestCLongUnmanagedCallersOnly() + { + ThisCallNative.C c = CreateCWithUnmanagedCallersOnlyVTable(2.0f, 3.0f); + CLong result = ThisCallNative.GetWidthAsLongFromManaged(&c); + + Assert.AreEqual((nint)c.width, result.Value); + } + private static ThisCallNative.C CreateCWithManagedVTable(float width, float height) { return new ThisCallNative.C @@ -241,6 +276,8 @@ private static ThisCallNative.C.VtableLayout* ManagedVtable (ThisCallNative.GetHeightAsIntFn)((ThisCallNative.C* c) => new ThisCallNative.IntWrapper { i = (int)c->height} )); managedVtable->getE = Marshal.GetFunctionPointerForDelegate( (ThisCallNative.GetEFn)((ThisCallNative.C* c) => c->dummy )); + managedVtable->getWidthAsLong = Marshal.GetFunctionPointerForDelegate( + (ThisCallNative.GetWidthAsLongFn)((ThisCallNative.C* c) => new CLong((nint)c->width))); } return managedVtable; } @@ -259,6 +296,7 @@ private static ThisCallNative.C.VtableLayout* UnmanagedCallersOnlyVtable unmanagedCallersOnlyVtable->getWidth = (IntPtr)(delegate* unmanaged[Thiscall])&GetWidth; unmanagedCallersOnlyVtable->getHeightAsInt = (IntPtr)(delegate* unmanaged[Thiscall])&GetHeightAsInt; unmanagedCallersOnlyVtable->getE = (IntPtr)(delegate* unmanaged[Thiscall])&GetE; + unmanagedCallersOnlyVtable->getWidthAsLong = (IntPtr)(delegate* unmanaged[Thiscall])&GetWidthAsLong; } return unmanagedCallersOnlyVtable; } @@ -297,4 +335,10 @@ private static ThisCallNative.E GetE(ThisCallNative.C* c) { return c->dummy; } + + [UnmanagedCallersOnly(CallConvs = new [] {typeof(CallConvThiscall)})] + private static CLong GetWidthAsLong(ThisCallNative.C* c) + { + return new CLong((nint)c->width); + } } diff --git a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsLayoutSeq.cs b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsLayoutSeq.cs index b096b13a9770d..837027c323630 100644 --- a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsLayoutSeq.cs +++ b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsLayoutSeq.cs @@ -31,7 +31,8 @@ enum StructID FixedBufferClassificationTestId, UnicodeCharArrayClassificationId, HFAId, - DoubleHFAId + DoubleHFAId, + Int32CLongId } private static void InitialArray(int[] iarr, int[] icarr) @@ -335,13 +336,16 @@ public static int Main() [DllImport("MarshalStructAsParam")] static extern HFA GetHFA(float f1, float f2, float f3, float f4); - + [DllImport("MarshalStructAsParam")] static extern float ProductHFA(HFA hfa); [DllImport("MarshalStructAsParam")] static extern double ProductDoubleHFA(DoubleHFA hfa); + [DllImport("MarshalStructAsParam")] + static extern Int32CLongStruct AddCLongs(Int32CLongStruct lhs, Int32CLongStruct rhs); + [DllImport("MarshalStructAsParam")] static extern ManyInts GetMultiplesOf(int i); @@ -376,7 +380,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) { failures++; } - break; + break; case StructID.InnerArraySequentialId: InnerArraySequential source_ias = Helper.NewInnerArraySequential(1, 1.0F, "some string"); InnerArraySequential clone_ias = Helper.NewInnerArraySequential(1, 1.0F, "some string"); @@ -391,7 +395,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) { failures++; } - break; + break; case StructID.CharSetAnsiSequentialId: CharSetAnsiSequential source_csas = Helper.NewCharSetAnsiSequential("some string", 'c'); CharSetAnsiSequential clone_csas = Helper.NewCharSetAnsiSequential("some string", 'c'); @@ -406,7 +410,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) { failures++; } - break; + break; case StructID.CharSetUnicodeSequentialId: CharSetUnicodeSequential source_csus = Helper.NewCharSetUnicodeSequential("some string", 'c'); CharSetUnicodeSequential clone_csus = Helper.NewCharSetUnicodeSequential("some string", 'c'); @@ -421,7 +425,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) { failures++; } - break; + break; case StructID.NumberSequentialId: NumberSequential source_ns = Helper.NewNumberSequential(Int32.MinValue, UInt32.MaxValue, short.MinValue, ushort.MaxValue, byte.MinValue, sbyte.MaxValue, Int16.MinValue, UInt16.MaxValue, -1234567890, 1234567890, 32.0F, 3.2); NumberSequential clone_ns = Helper.NewNumberSequential(Int32.MinValue, UInt32.MaxValue, short.MinValue, ushort.MaxValue, byte.MinValue, sbyte.MaxValue, Int16.MinValue, UInt16.MaxValue, -1234567890, 1234567890, 32.0F, 3.2); @@ -436,7 +440,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) { failures++; } - break; + break; case StructID.S3Id: int[] iarr = new int[256]; int[] icarr = new int[256]; @@ -455,7 +459,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) { failures++; } - break; + break; case StructID.S5Id: Enum1 enums = Enum1.e1; Enum1 enumcl = Enum1.e1; @@ -473,7 +477,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialAnsiId: strOne = new String('a', 512); strTwo = new String('b', 512); @@ -490,7 +494,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialUnicodeId: strOne = new String('a', 256); strTwo = new String('b', 256); @@ -507,7 +511,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) { failures++; } - break; + break; case StructID.S8Id: S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32); S8 cloneS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32); @@ -522,7 +526,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) { failures++; } - break; + break; case StructID.S9Id: S9 sourceS9 = Helper.NewS9(128, new TestDelegate1(testMethod)); S9 cloneS9 = Helper.NewS9(128, new TestDelegate1(testMethod)); @@ -537,7 +541,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) { failures++; } - break; + break; case StructID.IncludeOuterIntegerStructSequentialId: IncludeOuterIntegerStructSequential sourceIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(32, 32); IncludeOuterIntegerStructSequential cloneIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(32, 32); @@ -552,7 +556,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) { failures++; } - break; + break; case StructID.S11Id: S11 sourceS11 = Helper.NewS11((int*)new Int32(), 32); S11 cloneS11 = Helper.NewS11((int*)new Int64(), 32); @@ -594,7 +598,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) Console.WriteLine("\tFAILED! Managed to Native failed in MarshalStructAsParam_AsSeqByValIntWithInnerSequential.Expected:True;Actual:False"); failures++; } - break; + break; case StructID.SequentialWrapperId: SequentialWrapper sequentialWrapper = new SequentialWrapper { @@ -606,7 +610,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) Console.WriteLine("\tFAILED! Managed to Native failed in MarshalStructAsParam_AsSeqByValSequentialWrapper.Expected:True;Actual:False"); failures++; } - break; + break; case StructID.SequentialDoubleWrapperId: SequentialDoubleWrapper doubleWrapper = new SequentialDoubleWrapper { @@ -621,7 +625,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) Console.WriteLine("\tFAILED! Managed to Native failed in MarshalStructAsParam_AsSeqByValSequentialDoubleWrapper.Expected:True;Actual:False"); failures++; } - break; + break; case StructID.AggregateSequentialWrapperId: AggregateSequentialWrapper aggregateWrapper = new AggregateSequentialWrapper { @@ -641,7 +645,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) Console.WriteLine("\tFAILED! Managed to Native failed in MarshalStructAsParam_AsSeqByValSequentialAggregateSequentialWrapper.Expected:True;Actual:False"); failures++; } - break; + break; case StructID.FixedBufferClassificationTestId: Console.WriteLine("\tCalling MarshalStructAsParam_AsSeqByValFixedBufferClassificationTest with nonblittable struct..."); unsafe @@ -745,10 +749,38 @@ unsafe private static void MarshalStructAsParam_AsSeqByVal(StructID id) } break; } + case StructID.Int32CLongId: + { + Int32CLongStruct str1 = new Int32CLongStruct + { + i = 2, + l = new CLong(30) + }; + Int32CLongStruct str2 = new Int32CLongStruct + { + i = 10, + l = new CLong(50) + }; + + Int32CLongStruct expected = new Int32CLongStruct + { + i = 12, + l = new CLong(80) + }; + + Console.WriteLine("\tCalling AddCLongs."); + Int32CLongStruct actual = AddCLongs(str1, str2); + if (!expected.Equals(actual)) + { + Console.WriteLine($"\tFAILED! Expected {expected}. Actual {actual}"); + failures++; + } + break; + } default: Console.WriteLine("\tThere is not the struct id"); failures++; - break; + break; } } catch (Exception e) @@ -780,7 +812,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRef(StructID id) { failures++; } - break; + break; case StructID.InnerArraySequentialId: InnerArraySequential source_ias = Helper.NewInnerArraySequential(1, 1.0F, "some string"); InnerArraySequential change_ias = Helper.NewInnerArraySequential(77, 77.0F, "changed string"); @@ -809,7 +841,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRef(StructID id) { failures++; } - break; + break; case StructID.CharSetUnicodeSequentialId: CharSetUnicodeSequential source_csus = Helper.NewCharSetUnicodeSequential("some string", 'c'); CharSetUnicodeSequential change_csus = Helper.NewCharSetUnicodeSequential("change string", 'n'); @@ -824,7 +856,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRef(StructID id) { failures++; } - break; + break; case StructID.NumberSequentialId: NumberSequential source_ns = Helper.NewNumberSequential(Int32.MinValue, UInt32.MaxValue, short.MinValue, ushort.MaxValue, byte.MinValue, sbyte.MaxValue, Int16.MinValue, UInt16.MaxValue, -1234567890, 1234567890, 32.0F, 3.2); NumberSequential change_ns = Helper.NewNumberSequential(0, 32, 0, 16, 0, 8, 0, 16, 0, 64, 64.0F, 6.4); @@ -839,7 +871,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRef(StructID id) { failures++; } - break; + break; case StructID.S3Id: int[] iarr = new int[256]; int[] icarr = new int[256]; @@ -858,7 +890,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRef(StructID id) { failures++; } - break; + break; case StructID.S5Id: Enum1 enums = Enum1.e1; Enum1 enumch = Enum1.e2; @@ -875,7 +907,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRef(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialAnsiId: strOne = new String('a', 512); strTwo = new String('b', 512); @@ -892,7 +924,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRef(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialUnicodeId: strOne = new String('a', 256); strTwo = new String('b', 256); @@ -909,7 +941,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRef(StructID id) { failures++; } - break; + break; case StructID.S8Id: S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32); S8 changeS8 = Helper.NewS8("world", "HelloWorldAgain", false, 1, 256, 256, 64); @@ -924,7 +956,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRef(StructID id) { failures++; } - break; + break; case StructID.S9Id: S9 sourceS9 = Helper.NewS9(128, new TestDelegate1(testMethod)); S9 changeS9 = Helper.NewS9(256, null); @@ -939,7 +971,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRef(StructID id) { failures++; } - break; + break; case StructID.IncludeOuterIntegerStructSequentialId: IncludeOuterIntegerStructSequential sourceIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(32, 32); IncludeOuterIntegerStructSequential changeIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(64, 64); @@ -954,7 +986,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRef(StructID id) { failures++; } - break; + break; case StructID.S11Id: S11 sourceS11 = Helper.NewS11((int*)new Int32(), 32); S11 changeS11 = Helper.NewS11((int*)(32), 64); @@ -969,11 +1001,11 @@ unsafe private static void MarshalStructAsParam_AsSeqByRef(StructID id) { failures++; } - break; + break; default: Console.WriteLine("\tThere is not the struct id"); failures++; - break; + break; } } catch (Exception e) @@ -1004,7 +1036,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValIn(StructID id) { failures++; } - break; + break; case StructID.InnerArraySequentialId: InnerArraySequential source_ias = Helper.NewInnerArraySequential(1, 1.0F, "some string"); InnerArraySequential clone_ias = Helper.NewInnerArraySequential(1, 1.0F, "some string"); @@ -1019,7 +1051,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValIn(StructID id) { failures++; } - break; + break; case StructID.CharSetAnsiSequentialId: CharSetAnsiSequential source_csas = Helper.NewCharSetAnsiSequential("some string", 'c'); CharSetAnsiSequential clone_csas = Helper.NewCharSetAnsiSequential("some string", 'c'); @@ -1034,7 +1066,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValIn(StructID id) { failures++; } - break; + break; case StructID.CharSetUnicodeSequentialId: CharSetUnicodeSequential source_csus = Helper.NewCharSetUnicodeSequential("some string", 'c'); CharSetUnicodeSequential clone_csus = Helper.NewCharSetUnicodeSequential("some string", 'c'); @@ -1049,7 +1081,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValIn(StructID id) { failures++; } - break; + break; case StructID.NumberSequentialId: NumberSequential source_ns = Helper.NewNumberSequential(Int32.MinValue, UInt32.MaxValue, short.MinValue, ushort.MaxValue, byte.MinValue, sbyte.MaxValue, Int16.MinValue, UInt16.MaxValue, -1234567890, 1234567890, 32.0F, 3.2); NumberSequential clone_ns = Helper.NewNumberSequential(Int32.MinValue, UInt32.MaxValue, short.MinValue, ushort.MaxValue, byte.MinValue, sbyte.MaxValue, Int16.MinValue, UInt16.MaxValue, -1234567890, 1234567890, 32.0F, 3.2); @@ -1064,7 +1096,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValIn(StructID id) { failures++; } - break; + break; case StructID.S3Id: int[] iarr = new int[256]; int[] icarr = new int[256]; @@ -1083,7 +1115,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValIn(StructID id) { failures++; } - break; + break; case StructID.S5Id: Enum1 enums = Enum1.e1; Enum1 enumcl = Enum1.e1; @@ -1100,7 +1132,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValIn(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialAnsiId: strOne = new String('a', 512); strTwo = new String('b', 512); @@ -1117,7 +1149,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValIn(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialUnicodeId: strOne = new String('a', 256); strTwo = new String('b', 256); @@ -1134,7 +1166,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValIn(StructID id) { failures++; } - break; + break; case StructID.S8Id: S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32); S8 cloneS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32); @@ -1149,7 +1181,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValIn(StructID id) { failures++; } - break; + break; case StructID.S9Id: S9 sourceS9 = Helper.NewS9(128, new TestDelegate1(testMethod)); S9 cloneS9 = Helper.NewS9(128, new TestDelegate1(testMethod)); @@ -1164,7 +1196,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValIn(StructID id) { failures++; } - break; + break; case StructID.IncludeOuterIntegerStructSequentialId: IncludeOuterIntegerStructSequential sourceIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(32, 32); IncludeOuterIntegerStructSequential cloneIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(32, 32); @@ -1179,7 +1211,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValIn(StructID id) { failures++; } - break; + break; case StructID.S11Id: S11 sourceS11 = Helper.NewS11((int*)new Int32(), 32); S11 cloneS11 = Helper.NewS11((int*)new Int64(), 32); @@ -1199,7 +1231,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValIn(StructID id) default: Console.WriteLine("\tThere is not the struct id"); failures++; - break; + break; } } catch (Exception e) @@ -1230,7 +1262,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefIn(StructID id) { failures++; } - break; + break; case StructID.InnerArraySequentialId: InnerArraySequential source_ias = Helper.NewInnerArraySequential(1, 1.0F, "some string"); InnerArraySequential clone_ias = Helper.NewInnerArraySequential(1, 1.0F, "some string"); @@ -1245,7 +1277,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefIn(StructID id) { failures++; } - break; + break; case StructID.CharSetAnsiSequentialId: CharSetAnsiSequential source_csas = Helper.NewCharSetAnsiSequential("some string", 'c'); CharSetAnsiSequential clone_csas = Helper.NewCharSetAnsiSequential("some string", 'c'); @@ -1260,7 +1292,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefIn(StructID id) { failures++; } - break; + break; case StructID.CharSetUnicodeSequentialId: CharSetUnicodeSequential source_csus = Helper.NewCharSetUnicodeSequential("some string", 'c'); CharSetUnicodeSequential clone_csus = Helper.NewCharSetUnicodeSequential("some string", 'c'); @@ -1275,7 +1307,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefIn(StructID id) { failures++; } - break; + break; case StructID.NumberSequentialId: NumberSequential source_ns = Helper.NewNumberSequential(Int32.MinValue, UInt32.MaxValue, short.MinValue, ushort.MaxValue, byte.MinValue, sbyte.MaxValue, Int16.MinValue, UInt16.MaxValue, -1234567890, 1234567890, 32.0F, 3.2); NumberSequential change_ns = Helper.NewNumberSequential(0, 32, 0, 16, 0, 8, 0, 16, 0, 64, 64.0F, 6.4); @@ -1290,7 +1322,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefIn(StructID id) { failures++; } - break; + break; case StructID.S3Id: int[] iarr = new int[256]; int[] icarr = new int[256]; @@ -1309,7 +1341,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefIn(StructID id) { failures++; } - break; + break; case StructID.S5Id: Enum1 enums = Enum1.e1; Enum1 enumcl = Enum1.e1; @@ -1326,7 +1358,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefIn(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialAnsiId: strOne = new String('a', 512); strTwo = new String('b', 512); @@ -1343,7 +1375,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefIn(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialUnicodeId: strOne = new String('a', 256); strTwo = new String('b', 256); @@ -1360,7 +1392,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefIn(StructID id) { failures++; } - break; + break; case StructID.S8Id: S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32); S8 cloneS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32); @@ -1375,7 +1407,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefIn(StructID id) { failures++; } - break; + break; case StructID.S9Id: S9 sourceS9 = Helper.NewS9(128, new TestDelegate1(testMethod)); S9 cloneS9 = Helper.NewS9(128, new TestDelegate1(testMethod)); @@ -1390,7 +1422,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefIn(StructID id) { failures++; } - break; + break; case StructID.IncludeOuterIntegerStructSequentialId: IncludeOuterIntegerStructSequential sourceIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(32, 32); IncludeOuterIntegerStructSequential changeIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(64, 64); @@ -1405,7 +1437,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefIn(StructID id) { failures++; } - break; + break; case StructID.S11Id: S11 sourceS11 = Helper.NewS11((int*)new Int32(), 32); S11 changeS11 = Helper.NewS11((int*)(32), 64); @@ -1420,11 +1452,11 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefIn(StructID id) { failures++; } - break; + break; default: Console.WriteLine("\tThere is not the struct id"); failures++; - break; + break; } } catch (Exception e) @@ -1455,7 +1487,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValOut(StructID id) { failures++; } - break; + break; case StructID.InnerArraySequentialId: InnerArraySequential source_ias = Helper.NewInnerArraySequential(1, 1.0F, "some string"); InnerArraySequential clone_ias = Helper.NewInnerArraySequential(1, 1.0F, "some string"); @@ -1470,7 +1502,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValOut(StructID id) { failures++; } - break; + break; case StructID.CharSetAnsiSequentialId: CharSetAnsiSequential source_csas = Helper.NewCharSetAnsiSequential("some string", 'c'); CharSetAnsiSequential clone_csas = Helper.NewCharSetAnsiSequential("some string", 'c'); @@ -1485,7 +1517,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValOut(StructID id) { failures++; } - break; + break; case StructID.CharSetUnicodeSequentialId: CharSetUnicodeSequential source_csus = Helper.NewCharSetUnicodeSequential("some string", 'c'); CharSetUnicodeSequential clone_csus = Helper.NewCharSetUnicodeSequential("some string", 'c'); @@ -1500,7 +1532,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValOut(StructID id) { failures++; } - break; + break; case StructID.NumberSequentialId: NumberSequential source_ns = Helper.NewNumberSequential(Int32.MinValue, UInt32.MaxValue, short.MinValue, ushort.MaxValue, byte.MinValue, sbyte.MaxValue, Int16.MinValue, UInt16.MaxValue, -1234567890, 1234567890, 32.0F, 3.2); NumberSequential clone_ns = Helper.NewNumberSequential(Int32.MinValue, UInt32.MaxValue, short.MinValue, ushort.MaxValue, byte.MinValue, sbyte.MaxValue, Int16.MinValue, UInt16.MaxValue, -1234567890, 1234567890, 32.0F, 3.2); @@ -1515,7 +1547,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValOut(StructID id) { failures++; } - break; + break; case StructID.S3Id: int[] iarr = new int[256]; int[] icarr = new int[256]; @@ -1534,7 +1566,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValOut(StructID id) { failures++; } - break; + break; case StructID.S5Id: Enum1 enums = Enum1.e1; Enum1 enumcl = Enum1.e1; @@ -1551,7 +1583,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValOut(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialAnsiId: strOne = new String('a', 512); strTwo = new String('b', 512); @@ -1568,7 +1600,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValOut(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialUnicodeId: strOne = new String('a', 256); strTwo = new String('b', 256); @@ -1585,7 +1617,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValOut(StructID id) { failures++; } - break; + break; case StructID.S8Id: S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32); S8 cloneS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32); @@ -1600,7 +1632,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValOut(StructID id) { failures++; } - break; + break; case StructID.S9Id: S9 sourceS9 = Helper.NewS9(128, new TestDelegate1(testMethod)); S9 cloneS9 = Helper.NewS9(128, new TestDelegate1(testMethod)); @@ -1615,7 +1647,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValOut(StructID id) { failures++; } - break; + break; case StructID.IncludeOuterIntegerStructSequentialId: IncludeOuterIntegerStructSequential sourceIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(32, 32); IncludeOuterIntegerStructSequential cloneIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(32, 32); @@ -1630,7 +1662,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValOut(StructID id) { failures++; } - break; + break; case StructID.S11Id: S11 sourceS11 = Helper.NewS11((int*)32, 32); S11 cloneS11 = Helper.NewS11((int*)32, 32); @@ -1645,7 +1677,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValOut(StructID id) { failures++; } - break; + break; default: Console.WriteLine("\tThere is not the struct id"); failures++; @@ -1681,7 +1713,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefOut(StructID id) { failures++; } - break; + break; case StructID.InnerArraySequentialId: InnerArraySequential source_ias = Helper.NewInnerArraySequential(1, 1.0F, "some string"); InnerArraySequential change_ias = Helper.NewInnerArraySequential(77, 77.0F, "changed string"); @@ -1696,7 +1728,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefOut(StructID id) { failures++; } - break; + break; case StructID.CharSetAnsiSequentialId: CharSetAnsiSequential source_csas = Helper.NewCharSetAnsiSequential("some string", 'c'); CharSetAnsiSequential changeStr1 = Helper.NewCharSetAnsiSequential("change string", 'n'); @@ -1711,7 +1743,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefOut(StructID id) { failures++; } - break; + break; case StructID.CharSetUnicodeSequentialId: CharSetUnicodeSequential source_csus = Helper.NewCharSetUnicodeSequential("some string", 'c'); CharSetUnicodeSequential change_csus = Helper.NewCharSetUnicodeSequential("change string", 'n'); @@ -1726,7 +1758,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefOut(StructID id) { failures++; } - break; + break; case StructID.NumberSequentialId: NumberSequential source_ns = Helper.NewNumberSequential(Int32.MinValue, UInt32.MaxValue, short.MinValue, ushort.MaxValue, byte.MinValue, sbyte.MaxValue, Int16.MinValue, UInt16.MaxValue, -1234567890, 1234567890, 32.0F, 3.2); NumberSequential change_ns = Helper.NewNumberSequential(0, 32, 0, 16, 0, 8, 0, 16, 0, 64, 64.0F, 6.4); @@ -1741,7 +1773,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefOut(StructID id) { failures++; } - break; + break; case StructID.S3Id: int[] iarr = new int[256]; int[] icarr = new int[256]; @@ -1760,7 +1792,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefOut(StructID id) { failures++; } - break; + break; case StructID.S5Id: Enum1 enums = Enum1.e1; Enum1 enumch = Enum1.e2; @@ -1777,7 +1809,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefOut(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialAnsiId: strOne = new String('a', 512); strTwo = new String('b', 512); @@ -1794,7 +1826,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefOut(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialUnicodeId: strOne = new String('a', 256); strTwo = new String('b', 256); @@ -1811,7 +1843,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefOut(StructID id) { failures++; } - break; + break; case StructID.S8Id: S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32); S8 changeS8 = Helper.NewS8("world", "HelloWorldAgain", false, 1, 256, 256, 64); @@ -1826,7 +1858,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefOut(StructID id) { failures++; } - break; + break; case StructID.S9Id: S9 sourceS9 = Helper.NewS9(128, new TestDelegate1(testMethod)); @@ -1845,7 +1877,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefOut(StructID id) { Console.WriteLine("\tPASSED!"); } - break; + break; case StructID.IncludeOuterIntegerStructSequentialId: IncludeOuterIntegerStructSequential sourceIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(32, 32); IncludeOuterIntegerStructSequential changeIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(64, 64); @@ -1860,7 +1892,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefOut(StructID id) { failures++; } - break; + break; case StructID.S11Id: S11 sourceS11 = Helper.NewS11((int*)new Int32(), 32); S11 changeS11 = Helper.NewS11((int*)(32), 64); @@ -1875,7 +1907,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefOut(StructID id) { failures++; } - break; + break; default: Console.WriteLine("\tThere is not the struct id"); failures++; @@ -1910,7 +1942,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValInOut(StructID id) { failures++; } - break; + break; case StructID.InnerArraySequentialId: InnerArraySequential source_ias = Helper.NewInnerArraySequential(1, 1.0F, "some string"); InnerArraySequential clone_ias = Helper.NewInnerArraySequential(1, 1.0F, "some string"); @@ -1925,7 +1957,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValInOut(StructID id) { failures++; } - break; + break; case StructID.CharSetAnsiSequentialId: CharSetAnsiSequential source_csas = Helper.NewCharSetAnsiSequential("some string", 'c'); CharSetAnsiSequential clone_csas = Helper.NewCharSetAnsiSequential("some string", 'c'); @@ -1940,7 +1972,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValInOut(StructID id) { failures++; } - break; + break; case StructID.CharSetUnicodeSequentialId: CharSetUnicodeSequential source_csus = Helper.NewCharSetUnicodeSequential("some string", 'c'); CharSetUnicodeSequential clone_csus = Helper.NewCharSetUnicodeSequential("some string", 'c'); @@ -1955,7 +1987,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValInOut(StructID id) { failures++; } - break; + break; case StructID.NumberSequentialId: NumberSequential source_ns = Helper.NewNumberSequential(Int32.MinValue, UInt32.MaxValue, short.MinValue, ushort.MaxValue, byte.MinValue, sbyte.MaxValue, Int16.MinValue, UInt16.MaxValue, -1234567890, 1234567890, 32.0F, 3.2); NumberSequential clone_ns = Helper.NewNumberSequential(Int32.MinValue, UInt32.MaxValue, short.MinValue, ushort.MaxValue, byte.MinValue, sbyte.MaxValue, Int16.MinValue, UInt16.MaxValue, -1234567890, 1234567890, 32.0F, 3.2); @@ -1970,7 +2002,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValInOut(StructID id) { failures++; } - break; + break; case StructID.S3Id: int[] iarr = new int[256]; int[] icarr = new int[256]; @@ -1989,7 +2021,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValInOut(StructID id) { failures++; } - break; + break; case StructID.S5Id: Enum1 enums = Enum1.e1; Enum1 enumcl = Enum1.e1; @@ -2006,7 +2038,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValInOut(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialAnsiId: strOne = new String('a', 512); strTwo = new String('b', 512); @@ -2023,7 +2055,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValInOut(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialUnicodeId: strOne = new String('a', 256); strTwo = new String('b', 256); @@ -2040,7 +2072,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValInOut(StructID id) { failures++; } - break; + break; case StructID.S8Id: S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32); S8 cloneS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32); @@ -2055,7 +2087,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValInOut(StructID id) { failures++; } - break; + break; case StructID.S9Id: S9 sourceS9 = Helper.NewS9(128, new TestDelegate1(testMethod)); S9 cloneS9 = Helper.NewS9(128, new TestDelegate1(testMethod)); @@ -2070,7 +2102,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValInOut(StructID id) { failures++; } - break; + break; case StructID.IncludeOuterIntegerStructSequentialId: IncludeOuterIntegerStructSequential sourceIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(32, 32); IncludeOuterIntegerStructSequential cloneIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(32, 32); @@ -2085,7 +2117,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValInOut(StructID id) { failures++; } - break; + break; case StructID.S11Id: S11 sourceS11 = Helper.NewS11((int*)new Int32(), 32); S11 cloneS11 = Helper.NewS11((int*)new Int64(), 32); @@ -2100,7 +2132,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByValInOut(StructID id) { failures++; } - break; + break; default: Console.WriteLine("\tThere is not the struct id"); failures++; @@ -2136,7 +2168,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefInOut(StructID id) { failures++; } - break; + break; case StructID.InnerArraySequentialId: InnerArraySequential source_ias = Helper.NewInnerArraySequential(1, 1.0F, "some string"); InnerArraySequential change_ias = Helper.NewInnerArraySequential(77, 77.0F, "changed string"); @@ -2151,7 +2183,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefInOut(StructID id) { failures++; } - break; + break; case StructID.CharSetAnsiSequentialId: CharSetAnsiSequential source_csas = Helper.NewCharSetAnsiSequential("some string", 'c'); CharSetAnsiSequential changeStr1 = Helper.NewCharSetAnsiSequential("change string", 'n'); @@ -2166,7 +2198,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefInOut(StructID id) { failures++; } - break; + break; case StructID.CharSetUnicodeSequentialId: CharSetUnicodeSequential source_csus = Helper.NewCharSetUnicodeSequential("some string", 'c'); CharSetUnicodeSequential change_csus = Helper.NewCharSetUnicodeSequential("change string", 'n'); @@ -2181,7 +2213,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefInOut(StructID id) { failures++; } - break; + break; case StructID.NumberSequentialId: NumberSequential source_ns = Helper.NewNumberSequential(Int32.MinValue, UInt32.MaxValue, short.MinValue, ushort.MaxValue, byte.MinValue, sbyte.MaxValue, Int16.MinValue, UInt16.MaxValue, -1234567890, 1234567890, 32.0F, 3.2); NumberSequential change_ns = Helper.NewNumberSequential(0, 32, 0, 16, 0, 8, 0, 16, 0, 64, 64.0F, 6.4); @@ -2196,7 +2228,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefInOut(StructID id) { failures++; } - break; + break; case StructID.S3Id: int[] iarr = new int[256]; int[] icarr = new int[256]; @@ -2215,7 +2247,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefInOut(StructID id) { failures++; } - break; + break; case StructID.S5Id: Enum1 enums = Enum1.e1; Enum1 enumch = Enum1.e2; @@ -2232,7 +2264,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefInOut(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialAnsiId: strOne = new String('a', 512); strTwo = new String('b', 512); @@ -2249,7 +2281,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefInOut(StructID id) { failures++; } - break; + break; case StructID.StringStructSequentialUnicodeId: strOne = new String('a', 256); strTwo = new String('b', 256); @@ -2266,7 +2298,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefInOut(StructID id) { failures++; } - break; + break; case StructID.S8Id: S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32); S8 changeS8 = Helper.NewS8("world", "HelloWorldAgain", false, 1, 256, 256, 64); @@ -2281,7 +2313,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefInOut(StructID id) { failures++; } - break; + break; case StructID.S9Id: S9 sourceS9 = Helper.NewS9(128, new TestDelegate1(testMethod)); S9 changeS9 = Helper.NewS9(256, null); @@ -2296,7 +2328,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefInOut(StructID id) { failures++; } - break; + break; case StructID.IncludeOuterIntegerStructSequentialId: IncludeOuterIntegerStructSequential sourceIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(32, 32); IncludeOuterIntegerStructSequential changeIncludeOuterIntegerStructSequential = Helper.NewIncludeOuterIntegerStructSequential(64, 64); @@ -2311,7 +2343,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefInOut(StructID id) { failures++; } - break; + break; case StructID.S11Id: S11 sourceS11 = Helper.NewS11((int*)new Int32(), 32); S11 changeS11 = Helper.NewS11((int*)(32), 64); @@ -2326,7 +2358,7 @@ unsafe private static void MarshalStructAsParam_AsSeqByRefInOut(StructID id) { failures++; } - break; + break; default: Console.WriteLine("\tThere is not the struct id"); failures++; @@ -2371,6 +2403,7 @@ private static void RunMarshalSeqStructAsParamByVal() MarshalStructAsParam_AsSeqByVal(StructID.UnicodeCharArrayClassificationId); MarshalStructAsParam_AsSeqByVal(StructID.HFAId); MarshalStructAsParam_AsSeqByVal(StructID.DoubleHFAId); + MarshalStructAsParam_AsSeqByVal(StructID.Int32CLongId); } [SecuritySafeCritical] diff --git a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp index a7f5d17de6c48..9278650d20dce 100644 --- a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp +++ b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp @@ -1226,7 +1226,7 @@ extern "C" DLL_EXPORT double STDMETHODCALLTYPE ProductDoubleHFA(DoubleHFA hfa) extern "C" DLL_EXPORT ManyInts STDMETHODCALLTYPE GetMultiplesOf(int value) { - ManyInts multiples = + ManyInts multiples = { value * 1, value * 2, @@ -1235,7 +1235,7 @@ extern "C" DLL_EXPORT ManyInts STDMETHODCALLTYPE GetMultiplesOf(int value) value * 5, value * 6, value * 7, - value * 8, + value * 8, value * 9, value * 10, value * 11, @@ -1292,3 +1292,8 @@ extern "C" DLL_EXPORT void STDMETHODCALLTYPE MarshalStructAsParam_DelegateFieldM { // Nothing to do } + +extern "C" DLL_EXPORT Int32CLongStruct STDMETHODCALLTYPE AddCLongs(Int32CLongStruct lhs, Int32CLongStruct rhs) +{ + return { lhs.i + rhs.i, lhs.l + rhs.l }; +} diff --git a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h index a300af22d18f1..4a74572717890 100644 --- a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h +++ b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h @@ -87,7 +87,7 @@ bool IsCorrectINNER2(INNER2* p) } -struct InnerExplicit +struct InnerExplicit { #ifdef WINDOWS union @@ -97,7 +97,7 @@ struct InnerExplicit }; CHAR _unused0[4]; LPCSTR f3; - #endif + #endif #ifndef WINDOWS union @@ -107,7 +107,7 @@ struct InnerExplicit }; INT _unused0; LPCSTR f3; - #endif + #endif }; @@ -169,13 +169,13 @@ union InnerArrayExplicit { LONG64 _unused0; LPCSTR f4; - } s; + } s; }; #ifdef WINDOWS #ifdef HOST_64BIT -#pragma warning(push) +#pragma warning(push) #pragma warning(disable: 4201) // nonstandard extension used: nameless struct/union union OUTER3 { @@ -285,7 +285,7 @@ bool IsCorrectCharSetAnsiSequential(CharSetAnsiSequential* p) } -struct CharSetUnicodeSequential +struct CharSetUnicodeSequential { LPCWSTR f1; WCHAR f2; @@ -346,15 +346,15 @@ struct NumberSequential LONG64 i64; ULONG64 ui64; DOUBLE d; - INT i32; - UINT ui32; - SHORT s1; - WORD us1; - SHORT i16; + INT i32; + UINT ui32; + SHORT s1; + WORD us1; + SHORT i16; WORD ui16; FLOAT sgl; - BYTE b; - CHAR sb; + BYTE b; + CHAR sb; }; void PrintNumberSequential(NumberSequential* str, char const * name) { @@ -454,10 +454,10 @@ struct S4 INT age; LPCSTR name; }; -enum Enum1 +enum Enum1 { e1 = 1, - e2 = 3 + e2 = 3 }; struct S5 { @@ -529,7 +529,7 @@ void ChangeStringStructSequentialAnsi(StringStructSequentialAnsi* str) newFirst[512] = '\0'; newLast[512] = '\0'; - str->first = newFirst; + str->first = newFirst; str->last = newLast; } @@ -938,7 +938,7 @@ union OverlappingMultipleEightbyte float arr[3]; struct { - float padding[2]; + float padding[2]; int i; }; }; @@ -968,3 +968,9 @@ struct UnicodeCharArrayClassification WCHAR arr[6]; float f; }; + +struct Int32CLongStruct +{ + int32_t i; + long l; +}; diff --git a/src/tests/Interop/StructMarshalling/PInvoke/Struct.cs b/src/tests/Interop/StructMarshalling/PInvoke/Struct.cs index 293204527469f..ec47ca4945629 100644 --- a/src/tests/Interop/StructMarshalling/PInvoke/Struct.cs +++ b/src/tests/Interop/StructMarshalling/PInvoke/Struct.cs @@ -73,7 +73,7 @@ public struct INNER2 public int f1; [FieldOffset(4)] public float f2; - [FieldOffset(8)] + [FieldOffset(8)] public String f3; } @@ -145,7 +145,7 @@ public struct NumberSequential public UInt16 ui16; public Single sgl; public Byte b; - public SByte sb; + public SByte sb; } [StructLayout(LayoutKind.Sequential)] @@ -471,7 +471,7 @@ public NonBlittableFloat(float f) [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] private float[] arr; - + public float F => arr[0]; } @@ -503,3 +503,9 @@ public struct DelegateFieldMarshaling { public Delegate IntIntFunction; } + +public struct Int32CLongStruct +{ + public int i; + public CLong l; +} diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 41db21445c172..b8ebbfcaed1f8 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -1233,6 +1233,9 @@ needs triage + + https://github.com/dotnet/runtime/issues/46820 + needs triage