diff options
author | Jeremy Koritzinsky <jkoritzinsky@gmail.com> | 2018-11-15 17:14:35 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-15 17:14:35 -0800 |
commit | a08a66902cdfb8e713c1e11f56c3aea9ca6ece6c (patch) | |
tree | 0ec9b4dca8d487aba8be6c578903ae8fccba7054 /tests/src/Interop | |
parent | cd0fe8e2d781b21d18254b6414521f6399997f6e (diff) | |
download | coreclr-a08a66902cdfb8e713c1e11f56c3aea9ca6ece6c.tar.gz coreclr-a08a66902cdfb8e713c1e11f56c3aea9ca6ece6c.tar.bz2 coreclr-a08a66902cdfb8e713c1e11f56c3aea9ca6ece6c.zip |
Add tests for marshalling as VARIANT_BOOL or VARIANT (#20856)
* Add native side impl for VARIANT_BOOL test.
* More bool native code.
* Add VariantBool marshalling tests.
* Add infrastructure for tests for object -> VARIANT marshalling.
* Add variant tests for all built-in types.
* Clean up Variant tests.
* Add test for passing custom structure as object.
* Add test for VARIANT_BOOL byref.
* Added byref tests for VARIANT marshalling.
* Add field marshalling tests for VARIANT.
* Move ByValue tests to not have two sources of truth.
* Make managed code the one source of truth.
* Clean up formatting/unused methods.
* Clean up some whitespace issues.
* Add tests for BStrWrapper and CurrencyWrapper marshalling.
* Add UnknownWrapper tests.
* Add a test for VariantWrapper and PInvoke.
* PR Feedback.
* Remove ToString.
* Fix visibility
* Fix MSBuild import path.
* Clean up Variant tests.
Diffstat (limited to 'tests/src/Interop')
-rw-r--r-- | tests/src/Interop/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/src/Interop/PInvoke/Variant/CMakeLists.txt | 18 | ||||
-rw-r--r-- | tests/src/Interop/PInvoke/Variant/PInvokeDefs.cs | 200 | ||||
-rw-r--r-- | tests/src/Interop/PInvoke/Variant/VariantNative.cpp | 1115 | ||||
-rw-r--r-- | tests/src/Interop/PInvoke/Variant/VariantTest.cs | 294 | ||||
-rw-r--r-- | tests/src/Interop/PInvoke/Variant/VariantTest.csproj | 35 | ||||
-rw-r--r-- | tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp | 70 | ||||
-rw-r--r-- | tests/src/Interop/PrimitiveMarshalling/Bool/BoolTest.cs | 100 | ||||
-rw-r--r-- | tests/src/Interop/PrimitiveMarshalling/Bool/NativeMethodDef.cs | 54 |
9 files changed, 1858 insertions, 29 deletions
diff --git a/tests/src/Interop/CMakeLists.txt b/tests/src/Interop/CMakeLists.txt index 5d9c27b456..60fbde340c 100644 --- a/tests/src/Interop/CMakeLists.txt +++ b/tests/src/Interop/CMakeLists.txt @@ -56,6 +56,7 @@ add_subdirectory(DllImportAttribute/Simple) add_subdirectory(ExecInDefAppDom) if(WIN32) + add_subdirectory(PInvoke/Variant) add_subdirectory(PInvoke/Varargs) add_subdirectory(PInvoke/NativeCallManagedComVisible) # This test doesn't necessarily need to be Windows-only, but the implementation is very tied to Windows APIs diff --git a/tests/src/Interop/PInvoke/Variant/CMakeLists.txt b/tests/src/Interop/PInvoke/Variant/CMakeLists.txt new file mode 100644 index 0000000000..536ffb3840 --- /dev/null +++ b/tests/src/Interop/PInvoke/Variant/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required (VERSION 2.6) +project (VariantNative) +include_directories(${INC_PLATFORM_DIR}) +set(SOURCES VariantNative.cpp) + +# add the executable +add_library (VariantNative SHARED ${SOURCES}) + +if(WIN32) + list(APPEND LINK_LIBRARIES_ADDITIONAL + OleAut32.lib + ) +endif(WIN32) + +target_link_libraries(VariantNative ${LINK_LIBRARIES_ADDITIONAL}) + +# add the install targets +install (TARGETS VariantNative DESTINATION bin) diff --git a/tests/src/Interop/PInvoke/Variant/PInvokeDefs.cs b/tests/src/Interop/PInvoke/Variant/PInvokeDefs.cs new file mode 100644 index 0000000000..27e90ca2ff --- /dev/null +++ b/tests/src/Interop/PInvoke/Variant/PInvokeDefs.cs @@ -0,0 +1,200 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +#pragma warning disable CS0612, CS0618 +class VariantNative +{ + public struct CustomStruct + { + } + + public struct ObjectWrapper + { + [MarshalAs(UnmanagedType.Struct)] + public object value; + } + + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Byte(object obj, byte expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_SByte(object obj, sbyte expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Int16(object obj, short expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_UInt16(object obj, ushort expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Int32(object obj, int expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_UInt32(object obj, uint expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Int64(object obj, long expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_UInt64(object obj, ulong expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Single(object obj, float expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Double(object obj, double expected); + [DllImport(nameof(VariantNative), CharSet = CharSet.Unicode)] + public static extern bool Marshal_ByValue_String(object obj, [MarshalAs(UnmanagedType.BStr)] string expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Char(object obj, char expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Boolean(object obj, [MarshalAs(UnmanagedType.VariantBool)] bool expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_DateTime(object obj, DateTime expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Decimal(object obj, decimal expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Currency(object obj, [MarshalAs(UnmanagedType.Currency)] decimal expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Missing(object obj); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Object(object obj); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Object_IUnknown(object obj); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Empty(object obj); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Null(object obj); + + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByValue_Invalid(object obj); + + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Byte(ref object obj, byte expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_SByte(ref object obj, sbyte expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Int16(ref object obj, short expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_UInt16(ref object obj, ushort expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Int32(ref object obj, int expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_UInt32(ref object obj, uint expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Int64(ref object obj, long expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_UInt64(ref object obj, ulong expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Single(ref object obj, float expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Double(ref object obj, double expected); + [DllImport(nameof(VariantNative), CharSet = CharSet.Unicode)] + public static extern bool Marshal_ByRef_String(ref object obj, [MarshalAs(UnmanagedType.BStr)] string expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Char(ref object obj, char expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Boolean(ref object obj, [MarshalAs(UnmanagedType.VariantBool)] bool expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_DateTime(ref object obj, DateTime expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Decimal(ref object obj, decimal expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Currency(ref object obj, [MarshalAs(UnmanagedType.Currency)] decimal expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Missing(ref object obj); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Object(ref object obj); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Object_IUnknown(ref object obj); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Empty(ref object obj); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ByRef_Null(ref object obj); + + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_ChangeVariantType(ref object obj, int expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Out(out object obj, int expected); + + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Byte(ObjectWrapper wrapper, byte expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_SByte(ObjectWrapper wrapper, sbyte expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Int16(ObjectWrapper wrapper, short expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_UInt16(ObjectWrapper wrapper, ushort expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Int32(ObjectWrapper wrapper, int expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_UInt32(ObjectWrapper wrapper, uint expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Int64(ObjectWrapper wrapper, long expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_UInt64(ObjectWrapper wrapper, ulong expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Single(ObjectWrapper wrapper, float expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Double(ObjectWrapper wrapper, double expected); + [DllImport(nameof(VariantNative), CharSet = CharSet.Unicode)] + public static extern bool Marshal_Struct_ByValue_String(ObjectWrapper wrapper, [MarshalAs(UnmanagedType.BStr)] string expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Char(ObjectWrapper wrapper, char expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Boolean(ObjectWrapper wrapper, [MarshalAs(UnmanagedType.VariantBool)] bool expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_DateTime(ObjectWrapper wrapper, DateTime expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Decimal(ObjectWrapper wrapper, decimal expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Currency(ObjectWrapper wrapper, [MarshalAs(UnmanagedType.Currency)] decimal expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Missing(ObjectWrapper wrapper); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Object(ObjectWrapper wrapper); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Object_IUnknown(ObjectWrapper wrapper); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Empty(ObjectWrapper wrapper); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByValue_Null(ObjectWrapper wrapper); + + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Byte(ref ObjectWrapper wrapper, byte expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_SByte(ref ObjectWrapper wrapper, sbyte expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Int16(ref ObjectWrapper wrapper, short expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_UInt16(ref ObjectWrapper wrapper, ushort expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Int32(ref ObjectWrapper wrapper, int expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_UInt32(ref ObjectWrapper wrapper, uint expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Int64(ref ObjectWrapper wrapper, long expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_UInt64(ref ObjectWrapper wrapper, ulong expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Single(ref ObjectWrapper wrapper, float expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Double(ref ObjectWrapper wrapper, double expected); + [DllImport(nameof(VariantNative), CharSet = CharSet.Unicode)] + public static extern bool Marshal_Struct_ByRef_String(ref ObjectWrapper wrapper, [MarshalAs(UnmanagedType.BStr)] string expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Char(ref ObjectWrapper wrapper, char expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Boolean(ref ObjectWrapper wrapper, [MarshalAs(UnmanagedType.VariantBool)] bool expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_DateTime(ref ObjectWrapper wrapper, DateTime expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Decimal(ref ObjectWrapper wrapper, decimal expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Currency(ref ObjectWrapper wrapper, [MarshalAs(UnmanagedType.Currency)] decimal expected); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Missing(ref ObjectWrapper wrapper); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Object(ref ObjectWrapper wrapper); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Object_IUnknown(ref ObjectWrapper wrapper); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Empty(ref ObjectWrapper wrapper); + [DllImport(nameof(VariantNative))] + public static extern bool Marshal_Struct_ByRef_Null(ref ObjectWrapper wrapper); +} diff --git a/tests/src/Interop/PInvoke/Variant/VariantNative.cpp b/tests/src/Interop/PInvoke/Variant/VariantNative.cpp new file mode 100644 index 0000000000..aea8519f3d --- /dev/null +++ b/tests/src/Interop/PInvoke/Variant/VariantNative.cpp @@ -0,0 +1,1115 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include <xplatform.h> +#include "platformdefines.h" + +#define LCID_ENGLISH MAKELCID(MAKELANGID(0x09, 0x01), SORT_DEFAULT) + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Byte(VARIANT value, BYTE expected) +{ + if (value.vt != VT_UI1) + { + printf("Invalid format. Expected VT_UI1.\n"); + return FALSE; + } + + return value.bVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_SByte(VARIANT value, CHAR expected) +{ + if (value.vt != VT_I1) + { + printf("Invalid format. Expected VT_I1.\n"); + return FALSE; + } + + return value.cVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Int16(VARIANT value, SHORT expected) +{ + if (value.vt != VT_I2) + { + printf("Invalid format. Expected VT_I2.\n"); + return FALSE; + } + + return value.iVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_UInt16(VARIANT value, USHORT expected) +{ + if (value.vt != VT_UI2) + { + printf("Invalid format. Expected VT_UI2.\n"); + return FALSE; + } + + return value.uiVal == expected ? TRUE : FALSE; +} +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Int32(VARIANT value, LONG expected) +{ + if (value.vt != VT_I4) + { + printf("Invalid format. Expected VT_I4.\n"); + return FALSE; + } + + return value.lVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_UInt32(VARIANT value, ULONG expected) +{ + if (value.vt != VT_UI4) + { + printf("Invalid format. Expected VT_UI4.\n"); + return FALSE; + } + + return value.ulVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Int64(VARIANT value, LONGLONG expected) +{ + if (value.vt != VT_I8) + { + printf("Invalid format. Expected VT_I8.\n"); + return FALSE; + } + + return value.llVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_UInt64(VARIANT value, ULONGLONG expected) +{ + if (value.vt != VT_UI8) + { + printf("Invalid format. Expected VT_UI8.\n"); + return FALSE; + } + + return value.ullVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Single(VARIANT value, FLOAT expected) +{ + if (value.vt != VT_R4) + { + printf("Invalid format. Expected VT_R4.\n"); + return FALSE; + } + + return value.fltVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Double(VARIANT value, DOUBLE expected) +{ + if (value.vt != VT_R8) + { + printf("Invalid format. Expected VT_R8.\n"); + return FALSE; + } + + return value.dblVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Char(VARIANT value, WCHAR expected) +{ + if (value.vt != VT_UI2) + { + printf("Invalid format. Expected VT_UI2.\n"); + return FALSE; + } + + return value.uiVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_String(VARIANT value, BSTR expected) +{ + if (value.vt != VT_BSTR) + { + printf("Invalid format. Expected VT_BSTR.\n"); + return FALSE; + } + + if (value.bstrVal == NULL || expected == NULL) + { + return value.bstrVal == NULL && expected == NULL; + } + + size_t len = TP_SysStringByteLen(value.bstrVal); + + return len == TP_SysStringByteLen(expected) && memcmp(value.bstrVal, expected, len) == 0; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Object(VARIANT value) +{ + + if (value.vt != VT_DISPATCH) + { + printf("Invalid format. Expected VT_DISPATCH.\n"); + return FALSE; + } + + + IDispatch* obj = value.pdispVal; + + if (obj == NULL) + { + printf("Marshal_ByValue (Native side) recieved an invalid IDispatch pointer\n"); + return FALSE; + } + + obj->AddRef(); + + obj->Release(); + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Object_IUnknown(VARIANT value) +{ + + if (value.vt != VT_UNKNOWN) + { + printf("Invalid format. Expected VT_UNKNOWN.\n"); + return FALSE; + } + + + IUnknown* obj = value.punkVal; + + if (obj == NULL) + { + printf("Marshal_ByValue (Native side) recieved an invalid IUnknown pointer\n"); + return FALSE; + } + + obj->AddRef(); + + obj->Release(); + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Missing(VARIANT value) +{ + if (value.vt != VT_ERROR) + { + printf("Invalid format. Expected VT_ERROR.\n"); + return FALSE; + } + + return value.scode == DISP_E_PARAMNOTFOUND ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Empty(VARIANT value) +{ + if (value.vt != VT_EMPTY) + { + printf("Invalid format. Expected VT_EMPTY. \n"); + return FALSE; + } + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Boolean(VARIANT value, VARIANT_BOOL expected) +{ + if (value.vt != VT_BOOL) + { + printf("Invalid format. Expected VT_BOOL.\n"); + return FALSE; + } + + return value.boolVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_DateTime(VARIANT value, DATE expected) +{ + if (value.vt != VT_DATE) + { + printf("Invalid format. Expected VT_BYREF.\n"); + return FALSE; + } + + return value.date == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Decimal(VARIANT value, DECIMAL expected) +{ + if (value.vt != VT_DECIMAL) + { + printf("Invalid format. Expected VT_DECIMAL.\n"); + return FALSE; + } + + expected.wReserved = VT_DECIMAL; // The wReserved field in DECIMAL overlaps with the vt field in VARIANT + + return memcmp(&value.decVal, &expected, sizeof(DECIMAL)) == 0; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Currency(VARIANT value, CY expected) +{ + if (value.vt != VT_CY) + { + printf("Invalid format. Expected VT_CY.\n"); + return FALSE; + } + + return memcmp(&value.cyVal, &expected, sizeof(CY)) == 0; +} + + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Null(VARIANT value) +{ + if (value.vt != VT_NULL) + { + printf("Invalid format. Expected VT_NULL. \n"); + return FALSE; + } + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByValue_Invalid(VARIANT value) +{ + return FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Byte(VARIANT* value, BYTE expected) +{ + if (value->vt != VT_UI1) + { + printf("Invalid format. Expected VT_UI1.\n"); + return FALSE; + } + + return value->bVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_SByte(VARIANT* value, CHAR expected) +{ + if (value->vt != VT_I1) + { + printf("Invalid format. Expected VT_I1.\n"); + return FALSE; + } + + return value->cVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Int16(VARIANT* value, SHORT expected) +{ + if (value->vt != VT_I2) + { + printf("Invalid format. Expected VT_I2.\n"); + return FALSE; + } + + return value->iVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_UInt16(VARIANT* value, USHORT expected) +{ + if (value->vt != VT_UI2) + { + printf("Invalid format. Expected VT_UI2.\n"); + return FALSE; + } + + return value->uiVal == expected ? TRUE : FALSE; +} +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Int32(VARIANT* value, LONG expected) +{ + if (value->vt != VT_I4) + { + printf("Invalid format. Expected VT_I4.\n"); + return FALSE; + } + + return value->lVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_UInt32(VARIANT* value, ULONG expected) +{ + if (value->vt != VT_UI4) + { + printf("Invalid format. Expected VT_UI4.\n"); + return FALSE; + } + + return value->ulVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Int64(VARIANT* value, LONGLONG expected) +{ + if (value->vt != VT_I8) + { + printf("Invalid format. Expected VT_I8.\n"); + return FALSE; + } + + return value->llVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_UInt64(VARIANT* value, ULONGLONG expected) +{ + if (value->vt != VT_UI8) + { + printf("Invalid format. Expected VT_UI8.\n"); + return FALSE; + } + + return value->ullVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Single(VARIANT* value, FLOAT expected) +{ + if (value->vt != VT_R4) + { + printf("Invalid format. Expected VT_R4.\n"); + return FALSE; + } + + return value->fltVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Double(VARIANT* value, DOUBLE expected) +{ + if (value->vt != VT_R8) + { + printf("Invalid format. Expected VT_R8.\n"); + return FALSE; + } + + return value->dblVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Char(VARIANT* value, WCHAR expected) +{ + if (value->vt != VT_UI2) + { + printf("Invalid format. Expected VT_UI2.\n"); + return FALSE; + } + + return value->uiVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_String(VARIANT* value, BSTR expected) +{ + if (value->vt != VT_BSTR) + { + printf("Invalid format. Expected VT_BSTR.\n"); + return FALSE; + } + + if (value->bstrVal == NULL || expected == NULL) + { + return value->bstrVal == NULL && expected == NULL; + } + + size_t len = TP_SysStringByteLen(value->bstrVal); + + return len == TP_SysStringByteLen(expected) && memcmp(value->bstrVal, expected, len) == 0; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Object(VARIANT* value) +{ + + if (value->vt != VT_DISPATCH) + { + printf("Invalid format. Expected VT_DISPATCH.\n"); + return FALSE; + } + + + IDispatch* obj = value->pdispVal; + + if (obj == NULL) + { + printf("Marshal_ByRef (Native side) recieved an invalid IDispatch pointer\n"); + return FALSE; + } + + obj->AddRef(); + + obj->Release(); + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Object_IUnknown(VARIANT* value) +{ + + if (value->vt != VT_UNKNOWN) + { + printf("Invalid format. Expected VT_UNKNOWN.\n"); + return FALSE; + } + + + IUnknown* obj = value->punkVal; + + if (obj == NULL) + { + printf("Marshal_ByRef (Native side) recieved an invalid IUnknown pointer\n"); + return FALSE; + } + + obj->AddRef(); + + obj->Release(); + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Missing(VARIANT* value) +{ + if (value->vt != VT_ERROR) + { + printf("Invalid format. Expected VT_ERROR.\n"); + return FALSE; + } + + return value->scode == DISP_E_PARAMNOTFOUND ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Empty(VARIANT* value) +{ + if (value->vt != VT_EMPTY) + { + printf("Invalid format. Expected VT_EMPTY. \n"); + return FALSE; + } + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Boolean(VARIANT* value, VARIANT_BOOL expected) +{ + if (value->vt != VT_BOOL) + { + printf("Invalid format. Expected VT_BOOL.\n"); + return FALSE; + } + + return value->boolVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_DateTime(VARIANT* value, DATE expected) +{ + if (value->vt != VT_DATE) + { + printf("Invalid format. Expected VT_BYREF.\n"); + return FALSE; + } + + return value->date == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Decimal(VARIANT* value, DECIMAL expected) +{ + if (value->vt != VT_DECIMAL) + { + printf("Invalid format. Expected VT_DECIMAL.\n"); + return FALSE; + } + + expected.wReserved = VT_DECIMAL; // The wReserved field in DECIMAL overlaps with the vt field in VARIANT* + + return memcmp(&value->decVal, &expected, sizeof(DECIMAL)) == 0; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Currency(VARIANT* value, CY expected) +{ + if (value->vt != VT_CY) + { + printf("Invalid format. Expected VT_CY.\n"); + return FALSE; + } + + return memcmp(&value->cyVal, &expected, sizeof(CY)) == 0; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ByRef_Null(VARIANT* value) +{ + if (value->vt != VT_NULL) + { + printf("Invalid format. Expected VT_NULL. \n"); + return FALSE; + } + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Out(VARIANT* pValue, LONG expected) +{ + if (FAILED(VariantClear(pValue))) + { + printf("Failed to clear pValue.\n"); + return FALSE; + } + pValue->vt = VT_I4; + pValue->lVal = expected; + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_ChangeVariantType(VARIANT* pValue, LONG expected) +{ + if (FAILED(VariantClear(pValue))) + { + printf("Failed to clear pValue.\n"); + return FALSE; + } + pValue->vt = VT_I4; + pValue->lVal = expected; + + return TRUE; +} + +struct VariantWrapper +{ + VARIANT value; +}; + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Byte(VariantWrapper wrapper, BYTE expected) +{ + if (wrapper.value.vt != VT_UI1) + { + printf("Invalid format. Expected VT_UI1.\n"); + return FALSE; + } + + return wrapper.value.bVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_SByte(VariantWrapper wrapper, CHAR expected) +{ + if (wrapper.value.vt != VT_I1) + { + printf("Invalid format. Expected VT_I1.\n"); + return FALSE; + } + + return wrapper.value.cVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Int16(VariantWrapper wrapper, SHORT expected) +{ + if (wrapper.value.vt != VT_I2) + { + printf("Invalid format. Expected VT_I2.\n"); + return FALSE; + } + + return wrapper.value.iVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_UInt16(VariantWrapper wrapper, USHORT expected) +{ + if (wrapper.value.vt != VT_UI2) + { + printf("Invalid format. Expected VT_UI2.\n"); + return FALSE; + } + + return wrapper.value.uiVal == expected ? TRUE : FALSE; +} +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Int32(VariantWrapper wrapper, LONG expected) +{ + if (wrapper.value.vt != VT_I4) + { + printf("Invalid format. Expected VT_I4.\n"); + return FALSE; + } + + return wrapper.value.lVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_UInt32(VariantWrapper wrapper, ULONG expected) +{ + if (wrapper.value.vt != VT_UI4) + { + printf("Invalid format. Expected VT_UI4.\n"); + return FALSE; + } + + return wrapper.value.ulVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Int64(VariantWrapper wrapper, LONGLONG expected) +{ + if (wrapper.value.vt != VT_I8) + { + printf("Invalid format. Expected VT_I8.\n"); + return FALSE; + } + + return wrapper.value.llVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_UInt64(VariantWrapper wrapper, ULONGLONG expected) +{ + if (wrapper.value.vt != VT_UI8) + { + printf("Invalid format. Expected VT_UI8.\n"); + return FALSE; + } + + return wrapper.value.ullVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Single(VariantWrapper wrapper, FLOAT expected) +{ + if (wrapper.value.vt != VT_R4) + { + printf("Invalid format. Expected VT_R4.\n"); + return FALSE; + } + + return wrapper.value.fltVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Double(VariantWrapper wrapper, DOUBLE expected) +{ + if (wrapper.value.vt != VT_R8) + { + printf("Invalid format. Expected VT_R8.\n"); + return FALSE; + } + + return wrapper.value.dblVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Char(VariantWrapper wrapper, WCHAR expected) +{ + if (wrapper.value.vt != VT_UI2) + { + printf("Invalid format. Expected VT_UI2.\n"); + return FALSE; + } + + return wrapper.value.uiVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_String(VariantWrapper wrapper, BSTR expected) +{ + if (wrapper.value.vt != VT_BSTR) + { + printf("Invalid format. Expected VT_BSTR.\n"); + return FALSE; + } + + if (wrapper.value.bstrVal == NULL || expected == NULL) + { + return wrapper.value.bstrVal == NULL && expected == NULL; + } + + size_t len = TP_SysStringByteLen(wrapper.value.bstrVal); + + return len == TP_SysStringByteLen(expected) && memcmp(wrapper.value.bstrVal, expected, len) == 0; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Object(VariantWrapper wrapper) +{ + + if (wrapper.value.vt != VT_DISPATCH) + { + printf("Invalid format. Expected VT_DISPATCH.\n"); + return FALSE; + } + + + IDispatch* obj = wrapper.value.pdispVal; + + if (obj == NULL) + { + printf("Marshal_Struct_ByValue (Native side) recieved an invalid IDispatch pointer\n"); + return FALSE; + } + + obj->AddRef(); + + obj->Release(); + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Object_IUnknown(VariantWrapper wrapper) +{ + + if (wrapper.value.vt != VT_UNKNOWN) + { + printf("Invalid format. Expected VT_UNKNOWN.\n"); + return FALSE; + } + + + IUnknown* obj = wrapper.value.punkVal; + + if (obj == NULL) + { + printf("Marshal_Struct_ByValue (Native side) recieved an invalid IUnknown pointer\n"); + return FALSE; + } + + obj->AddRef(); + + obj->Release(); + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Missing(VariantWrapper wrapper) +{ + if (wrapper.value.vt != VT_ERROR) + { + printf("Invalid format. Expected VT_ERROR.\n"); + return FALSE; + } + + return wrapper.value.scode == DISP_E_PARAMNOTFOUND ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Empty(VariantWrapper wrapper) +{ + if (wrapper.value.vt != VT_EMPTY) + { + printf("Invalid format. Expected VT_EMPTY. \n"); + return FALSE; + } + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Boolean(VariantWrapper wrapper, VARIANT_BOOL expected) +{ + if (wrapper.value.vt != VT_BOOL) + { + printf("Invalid format. Expected VT_BOOL.\n"); + return FALSE; + } + + return wrapper.value.boolVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_DateTime(VariantWrapper wrapper, DATE expected) +{ + if (wrapper.value.vt != VT_DATE) + { + printf("Invalid format. Expected VT_Struct_ByValue.\n"); + return FALSE; + } + + return wrapper.value.date == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Decimal(VariantWrapper wrapper, DECIMAL expected) +{ + if (wrapper.value.vt != VT_DECIMAL) + { + printf("Invalid format. Expected VT_DECIMAL.\n"); + return FALSE; + } + + expected.wReserved = VT_DECIMAL; // The wReserved field in DECIMAL overlaps with the vt field in VARIANT* + + return memcmp(&wrapper.value.decVal, &expected, sizeof(DECIMAL)) == 0; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Currency(VariantWrapper wrapper, CY expected) +{ + if (wrapper.value.vt != VT_CY) + { + printf("Invalid format. Expected VT_CY.\n"); + return FALSE; + } + + return memcmp(&wrapper.value.cyVal, &expected, sizeof(CY)) == 0; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByValue_Null(VariantWrapper wrapper) +{ + if (wrapper.value.vt != VT_NULL) + { + printf("Invalid format. Expected VT_NULL. \n"); + return FALSE; + } + + return TRUE; +} + + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Byte(VariantWrapper* pWrapper, BYTE expected) +{ + if (pWrapper->value.vt != VT_UI1) + { + printf("Invalid format. Expected VT_UI1.\n"); + return FALSE; + } + + return pWrapper->value.bVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_SByte(VariantWrapper* pWrapper, CHAR expected) +{ + if (pWrapper->value.vt != VT_I1) + { + printf("Invalid format. Expected VT_I1.\n"); + return FALSE; + } + + return pWrapper->value.cVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Int16(VariantWrapper* pWrapper, SHORT expected) +{ + if (pWrapper->value.vt != VT_I2) + { + printf("Invalid format. Expected VT_I2.\n"); + return FALSE; + } + + return pWrapper->value.iVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_UInt16(VariantWrapper* pWrapper, USHORT expected) +{ + if (pWrapper->value.vt != VT_UI2) + { + printf("Invalid format. Expected VT_UI2.\n"); + return FALSE; + } + + return pWrapper->value.uiVal == expected ? TRUE : FALSE; +} +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Int32(VariantWrapper* pWrapper, LONG expected) +{ + if (pWrapper->value.vt != VT_I4) + { + printf("Invalid format. Expected VT_I4.\n"); + return FALSE; + } + + return pWrapper->value.lVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_UInt32(VariantWrapper* pWrapper, ULONG expected) +{ + if (pWrapper->value.vt != VT_UI4) + { + printf("Invalid format. Expected VT_UI4.\n"); + return FALSE; + } + + return pWrapper->value.ulVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Int64(VariantWrapper* pWrapper, LONGLONG expected) +{ + if (pWrapper->value.vt != VT_I8) + { + printf("Invalid format. Expected VT_I8.\n"); + return FALSE; + } + + return pWrapper->value.llVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_UInt64(VariantWrapper* pWrapper, ULONGLONG expected) +{ + if (pWrapper->value.vt != VT_UI8) + { + printf("Invalid format. Expected VT_UI8.\n"); + return FALSE; + } + + return pWrapper->value.ullVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Single(VariantWrapper* pWrapper, FLOAT expected) +{ + if (pWrapper->value.vt != VT_R4) + { + printf("Invalid format. Expected VT_R4.\n"); + return FALSE; + } + + return pWrapper->value.fltVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Double(VariantWrapper* pWrapper, DOUBLE expected) +{ + if (pWrapper->value.vt != VT_R8) + { + printf("Invalid format. Expected VT_R8.\n"); + return FALSE; + } + + return pWrapper->value.dblVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Char(VariantWrapper* pWrapper, WCHAR expected) +{ + if (pWrapper->value.vt != VT_UI2) + { + printf("Invalid format. Expected VT_UI2.\n"); + return FALSE; + } + + return pWrapper->value.uiVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_String(VariantWrapper* pWrapper, BSTR expected) +{ + if (pWrapper->value.vt != VT_BSTR) + { + printf("Invalid format. Expected VT_BSTR.\n"); + return FALSE; + } + + if (pWrapper->value.bstrVal == NULL || expected == NULL) + { + return pWrapper->value.bstrVal == NULL && expected == NULL; + } + + size_t len = TP_SysStringByteLen(pWrapper->value.bstrVal); + + return len == TP_SysStringByteLen(expected) && memcmp(pWrapper->value.bstrVal, expected, len) == 0; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Object(VariantWrapper* pWrapper) +{ + + if (pWrapper->value.vt != VT_DISPATCH) + { + printf("Invalid format. Expected VT_DISPATCH.\n"); + return FALSE; + } + + + IDispatch* obj = pWrapper->value.pdispVal; + + if (obj == NULL) + { + printf("Marshal_Struct_ByRef (Native side) recieved an invalid IDispatch pointer\n"); + return FALSE; + } + + obj->AddRef(); + + obj->Release(); + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Object_IUnknown(VariantWrapper* pWrapper) +{ + + if (pWrapper->value.vt != VT_UNKNOWN) + { + printf("Invalid format. Expected VT_UNKNOWN.\n"); + return FALSE; + } + + + IUnknown* obj = pWrapper->value.punkVal; + + if (obj == NULL) + { + printf("Marshal_Struct_ByRef (Native side) recieved an invalid IUnknown pointer\n"); + return FALSE; + } + + obj->AddRef(); + + obj->Release(); + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Missing(VariantWrapper* pWrapper) +{ + if (pWrapper->value.vt != VT_ERROR) + { + printf("Invalid format. Expected VT_ERROR.\n"); + return FALSE; + } + + return pWrapper->value.scode == DISP_E_PARAMNOTFOUND ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Empty(VariantWrapper* pWrapper) +{ + if (pWrapper->value.vt != VT_EMPTY) + { + printf("Invalid format. Expected VT_EMPTY. \n"); + return FALSE; + } + + return TRUE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Boolean(VariantWrapper* pWrapper, VARIANT_BOOL expected) +{ + if (pWrapper->value.vt != VT_BOOL) + { + printf("Invalid format. Expected VT_BOOL.\n"); + return FALSE; + } + + return pWrapper->value.boolVal == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_DateTime(VariantWrapper* pWrapper, DATE expected) +{ + if (pWrapper->value.vt != VT_DATE) + { + printf("Invalid format. Expected VT_Struct_ByRef.\n"); + return FALSE; + } + + return pWrapper->value.date == expected ? TRUE : FALSE; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Decimal(VariantWrapper* pWrapper, DECIMAL expected) +{ + if (pWrapper->value.vt != VT_DECIMAL) + { + printf("Invalid format. Expected VT_DECIMAL.\n"); + return FALSE; + } + + expected.wReserved = VT_DECIMAL; // The wReserved field in DECIMAL overlaps with the vt field in VARIANT* + + return memcmp(&pWrapper->value.decVal, &expected, sizeof(DECIMAL)) == 0; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Currency(VariantWrapper* pWrapper, CY expected) +{ + if (pWrapper->value.vt != VT_CY) + { + printf("Invalid format. Expected VT_CY.\n"); + return FALSE; + } + + return memcmp(&pWrapper->value.cyVal, &expected, sizeof(CY)) == 0; +} + +extern "C" BOOL DLL_EXPORT STDMETHODCALLTYPE Marshal_Struct_ByRef_Null(VariantWrapper* pWrapper) +{ + if (pWrapper->value.vt != VT_NULL) + { + printf("Invalid format. Expected VT_NULL. \n"); + return FALSE; + } + + return TRUE; +} + diff --git a/tests/src/Interop/PInvoke/Variant/VariantTest.cs b/tests/src/Interop/PInvoke/Variant/VariantTest.cs new file mode 100644 index 0000000000..ab16781561 --- /dev/null +++ b/tests/src/Interop/PInvoke/Variant/VariantTest.cs @@ -0,0 +1,294 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; +using TestLibrary; +using static VariantNative; + +#pragma warning disable CS0612, CS0618 +class Test +{ + private const byte NumericValue = 15; + + private const char CharValue = 'z'; + + private const string StringValue = "Abcdefg"; + + private const decimal DecimalValue = 74.25M; + + private static readonly DateTime DateValue = new DateTime(2018, 11, 6); + + private unsafe static void TestByValue() + { + Assert.IsTrue(Marshal_ByValue_Byte((byte)NumericValue, NumericValue)); + Assert.IsTrue(Marshal_ByValue_SByte((sbyte)NumericValue, (sbyte)NumericValue)); + Assert.IsTrue(Marshal_ByValue_Int16((short)NumericValue, NumericValue)); + Assert.IsTrue(Marshal_ByValue_UInt16((ushort)NumericValue, NumericValue)); + Assert.IsTrue(Marshal_ByValue_Int32((int)NumericValue, NumericValue)); + Assert.IsTrue(Marshal_ByValue_UInt32((uint)NumericValue, NumericValue)); + Assert.IsTrue(Marshal_ByValue_Int64((long)NumericValue, NumericValue)); + Assert.IsTrue(Marshal_ByValue_UInt64((ulong)NumericValue, NumericValue)); + Assert.IsTrue(Marshal_ByValue_Single((float)NumericValue, NumericValue)); + Assert.IsTrue(Marshal_ByValue_Double((double)NumericValue, NumericValue)); + Assert.IsTrue(Marshal_ByValue_String(StringValue, StringValue)); + Assert.IsTrue(Marshal_ByValue_String(new BStrWrapper(null), null)); + Assert.IsTrue(Marshal_ByValue_Char(CharValue, CharValue)); + Assert.IsTrue(Marshal_ByValue_Boolean(true, true)); + Assert.IsTrue(Marshal_ByValue_DateTime(DateValue, DateValue)); + Assert.IsTrue(Marshal_ByValue_Decimal(DecimalValue, DecimalValue)); + Assert.IsTrue(Marshal_ByValue_Currency(new CurrencyWrapper(DecimalValue), DecimalValue)); + Assert.IsTrue(Marshal_ByValue_Null(DBNull.Value)); + Assert.IsTrue(Marshal_ByValue_Missing(System.Reflection.Missing.Value)); + Assert.IsTrue(Marshal_ByValue_Empty(null)); + Assert.IsTrue(Marshal_ByValue_Object(new object())); + Assert.IsTrue(Marshal_ByValue_Object_IUnknown(new UnknownWrapper(new object()))); + Assert.Throws<ArgumentException>(() => Marshal_ByValue_Invalid(TimeSpan.Zero)); + Assert.Throws<NotSupportedException>(() => Marshal_ByValue_Invalid(new CustomStruct())); + Assert.Throws<ArgumentException>(() => Marshal_ByValue_Invalid(new VariantWrapper(CharValue))); + } + + private unsafe static void TestByRef() + { + object obj; + + obj = (byte)NumericValue; + Assert.IsTrue(Marshal_ByRef_Byte(ref obj, NumericValue)); + + obj = (sbyte)NumericValue; + Assert.IsTrue(Marshal_ByRef_SByte(ref obj, (sbyte)NumericValue)); + + obj = (short)NumericValue; + Assert.IsTrue(Marshal_ByRef_Int16(ref obj, NumericValue)); + + obj = (ushort)NumericValue; + Assert.IsTrue(Marshal_ByRef_UInt16(ref obj, NumericValue)); + + obj = (int)NumericValue; + Assert.IsTrue(Marshal_ByRef_Int32(ref obj, NumericValue)); + + obj = (uint)NumericValue; + Assert.IsTrue(Marshal_ByRef_UInt32(ref obj, NumericValue)); + + obj = (long)NumericValue; + Assert.IsTrue(Marshal_ByRef_Int64(ref obj, NumericValue)); + + obj = (ulong)NumericValue; + Assert.IsTrue(Marshal_ByRef_UInt64(ref obj, NumericValue)); + + obj = (float)NumericValue; + Assert.IsTrue(Marshal_ByRef_Single(ref obj, NumericValue)); + + obj = (double)NumericValue; + Assert.IsTrue(Marshal_ByRef_Double(ref obj, NumericValue)); + + obj = StringValue; + Assert.IsTrue(Marshal_ByRef_String(ref obj, StringValue)); + + obj = new BStrWrapper(null); + Assert.IsTrue(Marshal_ByRef_String(ref obj, null)); + + obj = CharValue; + Assert.IsTrue(Marshal_ByRef_Char(ref obj, CharValue)); + + obj = true; + Assert.IsTrue(Marshal_ByRef_Boolean(ref obj, true)); + + obj = DateValue; + Assert.IsTrue(Marshal_ByRef_DateTime(ref obj, DateValue)); + + obj = DecimalValue; + Assert.IsTrue(Marshal_ByRef_Decimal(ref obj, DecimalValue)); + + obj = new CurrencyWrapper(DecimalValue); + Assert.IsTrue(Marshal_ByRef_Currency(ref obj, DecimalValue)); + + obj = DBNull.Value; + Assert.IsTrue(Marshal_ByRef_Null(ref obj)); + + obj = System.Reflection.Missing.Value; + Assert.IsTrue(Marshal_ByRef_Missing(ref obj)); + + obj = null; + Assert.IsTrue(Marshal_ByRef_Empty(ref obj)); + + obj = new object(); + Assert.IsTrue(Marshal_ByRef_Object(ref obj)); + + obj = new UnknownWrapper(new object()); + Assert.IsTrue(Marshal_ByRef_Object_IUnknown(ref obj)); + + obj = DecimalValue; + Assert.IsTrue(Marshal_ChangeVariantType(ref obj, NumericValue)); + Assert.IsTrue(obj is int); + Assert.AreEqual(NumericValue, (int)obj); + } + + private unsafe static void TestOut() + { + Assert.IsTrue(Marshal_Out(out object obj, NumericValue)); + Assert.IsTrue(obj is int); + Assert.AreEqual(NumericValue, (int)obj); + } + + private unsafe static void TestFieldByValue() + { + ObjectWrapper wrapper = new ObjectWrapper(); + + wrapper.value = (byte)NumericValue; + Assert.IsTrue(Marshal_Struct_ByValue_Byte(wrapper, NumericValue)); + + wrapper.value = (sbyte)NumericValue; + Assert.IsTrue(Marshal_Struct_ByValue_SByte(wrapper, (sbyte)NumericValue)); + + wrapper.value = (short)NumericValue; + Assert.IsTrue(Marshal_Struct_ByValue_Int16(wrapper, NumericValue)); + + wrapper.value = (ushort)NumericValue; + Assert.IsTrue(Marshal_Struct_ByValue_UInt16(wrapper, NumericValue)); + + wrapper.value = (int)NumericValue; + Assert.IsTrue(Marshal_Struct_ByValue_Int32(wrapper, NumericValue)); + + wrapper.value = (uint)NumericValue; + Assert.IsTrue(Marshal_Struct_ByValue_UInt32(wrapper, NumericValue)); + + wrapper.value = (long)NumericValue; + Assert.IsTrue(Marshal_Struct_ByValue_Int64(wrapper, NumericValue)); + + wrapper.value = (ulong)NumericValue; + Assert.IsTrue(Marshal_Struct_ByValue_UInt64(wrapper, NumericValue)); + + wrapper.value = (float)NumericValue; + Assert.IsTrue(Marshal_Struct_ByValue_Single(wrapper, NumericValue)); + + wrapper.value = (double)NumericValue; + Assert.IsTrue(Marshal_Struct_ByValue_Double(wrapper, NumericValue)); + + wrapper.value = StringValue; + Assert.IsTrue(Marshal_Struct_ByValue_String(wrapper, StringValue)); + + wrapper.value = new BStrWrapper(null); + Assert.IsTrue(Marshal_Struct_ByValue_String(wrapper, null)); + + wrapper.value = CharValue; + Assert.IsTrue(Marshal_Struct_ByValue_Char(wrapper, CharValue)); + + wrapper.value = true; + Assert.IsTrue(Marshal_Struct_ByValue_Boolean(wrapper, true)); + + wrapper.value = DateValue; + Assert.IsTrue(Marshal_Struct_ByValue_DateTime(wrapper, DateValue)); + + wrapper.value = DecimalValue; + Assert.IsTrue(Marshal_Struct_ByValue_Decimal(wrapper, DecimalValue)); + + wrapper.value = new CurrencyWrapper(DecimalValue); + Assert.IsTrue(Marshal_Struct_ByValue_Currency(wrapper, DecimalValue)); + + wrapper.value = DBNull.Value; + Assert.IsTrue(Marshal_Struct_ByValue_Null(wrapper)); + + wrapper.value = System.Reflection.Missing.Value; + Assert.IsTrue(Marshal_Struct_ByValue_Missing(wrapper)); + + wrapper.value = null; + Assert.IsTrue(Marshal_Struct_ByValue_Empty(wrapper)); + + wrapper.value = new object(); + Assert.IsTrue(Marshal_Struct_ByValue_Object(wrapper)); + + wrapper.value = new UnknownWrapper(new object()); + Assert.IsTrue(Marshal_Struct_ByValue_Object_IUnknown(wrapper)); + } + + private unsafe static void TestFieldByRef() + { + ObjectWrapper wrapper = new ObjectWrapper(); + + wrapper.value = (byte)NumericValue; + Assert.IsTrue(Marshal_Struct_ByRef_Byte(ref wrapper, NumericValue)); + + wrapper.value = (sbyte)NumericValue; + Assert.IsTrue(Marshal_Struct_ByRef_SByte(ref wrapper, (sbyte)NumericValue)); + + wrapper.value = (short)NumericValue; + Assert.IsTrue(Marshal_Struct_ByRef_Int16(ref wrapper, NumericValue)); + + wrapper.value = (ushort)NumericValue; + Assert.IsTrue(Marshal_Struct_ByRef_UInt16(ref wrapper, NumericValue)); + + wrapper.value = (int)NumericValue; + Assert.IsTrue(Marshal_Struct_ByRef_Int32(ref wrapper, NumericValue)); + + wrapper.value = (uint)NumericValue; + Assert.IsTrue(Marshal_Struct_ByRef_UInt32(ref wrapper, NumericValue)); + + wrapper.value = (long)NumericValue; + Assert.IsTrue(Marshal_Struct_ByRef_Int64(ref wrapper, NumericValue)); + + wrapper.value = (ulong)NumericValue; + Assert.IsTrue(Marshal_Struct_ByRef_UInt64(ref wrapper, NumericValue)); + + wrapper.value = (float)NumericValue; + Assert.IsTrue(Marshal_Struct_ByRef_Single(ref wrapper, NumericValue)); + + wrapper.value = (double)NumericValue; + Assert.IsTrue(Marshal_Struct_ByRef_Double(ref wrapper, NumericValue)); + + wrapper.value = StringValue; + Assert.IsTrue(Marshal_Struct_ByRef_String(ref wrapper, StringValue)); + + wrapper.value = new BStrWrapper(null); + Assert.IsTrue(Marshal_Struct_ByRef_String(ref wrapper, null)); + + wrapper.value = CharValue; + Assert.IsTrue(Marshal_Struct_ByRef_Char(ref wrapper, CharValue)); + + wrapper.value = true; + Assert.IsTrue(Marshal_Struct_ByRef_Boolean(ref wrapper, true)); + + wrapper.value = DateValue; + Assert.IsTrue(Marshal_Struct_ByRef_DateTime(ref wrapper, DateValue)); + + wrapper.value = DecimalValue; + Assert.IsTrue(Marshal_Struct_ByRef_Decimal(ref wrapper, DecimalValue)); + + wrapper.value = new CurrencyWrapper(DecimalValue); + Assert.IsTrue(Marshal_Struct_ByRef_Currency(ref wrapper, DecimalValue)); + + wrapper.value = DBNull.Value; + Assert.IsTrue(Marshal_Struct_ByRef_Null(ref wrapper)); + + wrapper.value = System.Reflection.Missing.Value; + Assert.IsTrue(Marshal_Struct_ByRef_Missing(ref wrapper)); + + wrapper.value = null; + Assert.IsTrue(Marshal_Struct_ByRef_Empty(ref wrapper)); + + wrapper.value = new object(); + Assert.IsTrue(Marshal_Struct_ByRef_Object(ref wrapper)); + + wrapper.value = new UnknownWrapper(new object()); + Assert.IsTrue(Marshal_Struct_ByRef_Object_IUnknown(ref wrapper)); + } + + public static int Main() + { + try + { + TestByValue(); + TestByRef(); + TestOut(); + TestFieldByValue(); + TestFieldByRef(); + } + catch (Exception e) + { + Console.WriteLine($"Test failed: {e}"); + return 101; + } + return 100; + } +} diff --git a/tests/src/Interop/PInvoke/Variant/VariantTest.csproj b/tests/src/Interop/PInvoke/Variant/VariantTest.csproj new file mode 100644 index 0000000000..3826f46dd8 --- /dev/null +++ b/tests/src/Interop/PInvoke/Variant/VariantTest.csproj @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <Import Project="../../Interop.settings.targets" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <AssemblyName>VariantTest</AssemblyName> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid> + <OutputType>Exe</OutputType> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + + <!-- Test unsupported outside of windows --> + <TestUnsupportedOutsideWindows>true</TestUnsupportedOutsideWindows> + <DisableProjectBuild Condition="'$(TargetsUnix)' == 'true'">true</DisableProjectBuild> + </PropertyGroup> + <!-- Default configurations to help VS understand the configurations --> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup> + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + <ItemGroup> + <Compile Include="*.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="CMakeLists.txt" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp b/tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp index 23eeb2f03b..edbc8cb92a 100644 --- a/tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp +++ b/tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp @@ -173,4 +173,74 @@ extern "C" DLL_EXPORT bool STDMETHODCALLTYPE Marshal_As_Out(/*[Out]*/bool boolVa //Return return true; } + +#ifdef _WIN32 +extern "C" DLL_EXPORT bool STDMETHODCALLTYPE Marshal_ByValue_Variant(VARIANT_BOOL boolValue, bool expected) +{ + if (boolValue != (expected ? VARIANT_TRUE : VARIANT_FALSE)) + { + printf("Error in function Marshal_ByValue_Variant(Native Client)\n"); + + printf("Expected %s ", expected ? "true" : "false"); + printf("Actual %s (%hi)", boolValue == VARIANT_FALSE ? "false" : "(unknown variant value)", boolValue); + + return false; + } + + return true; +} + +extern "C" DLL_EXPORT bool STDMETHODCALLTYPE Marshal_Ref_Variant(VARIANT_BOOL* pBoolValue) +{ + if (*pBoolValue != (boolManaged ? VARIANT_TRUE : VARIANT_FALSE)) + { + printf("Error in function Marshal_ByValue_Variant(Native Client)\n"); + + printf("Expected %s ", boolManaged ? "true" : "false"); + printf("Actual %s (%hi)", *pBoolValue == VARIANT_FALSE ? "false" : "(unknown variant value)", *pBoolValue); + + return false; + } + + *pBoolValue = (boolNative ? VARIANT_TRUE : VARIANT_FALSE); + return true; +} + +struct ContainsVariantBool +{ + VARIANT_BOOL value; +}; + +extern "C" DLL_EXPORT bool STDMETHODCALLTYPE Marshal_ByValue_Struct_Variant(ContainsVariantBool value, bool expected) +{ + if (value.value != (expected ? VARIANT_TRUE : VARIANT_FALSE)) + { + printf("Error in function Marshal_ByValue_Variant(Native Client)\n"); + + printf("Expected %s ", expected ? "true" : "false"); + printf("Actual %s (%hi)", value.value == VARIANT_FALSE ? "false" : "(unknown variant value)", value.value); + + return false; + } + + return true; +} + +extern "C" DLL_EXPORT bool STDMETHODCALLTYPE Marshal_Ref_Struct_Variant(ContainsVariantBool* pBoolValue) +{ + if (pBoolValue->value != (boolManaged ? VARIANT_TRUE : VARIANT_FALSE)) + { + printf("Error in function Marshal_ByValue_Variant(Native Client)\n"); + + printf("Expected %s ", boolManaged ? "true" : "false"); + printf("Actual %s (%hi)", pBoolValue->value == VARIANT_FALSE ? "false" : "(unknown variant value)", pBoolValue->value); + + return false; + } + + pBoolValue->value = (boolNative ? VARIANT_TRUE : VARIANT_FALSE); + return true; +} + +#endif #pragma warning(pop) diff --git a/tests/src/Interop/PrimitiveMarshalling/Bool/BoolTest.cs b/tests/src/Interop/PrimitiveMarshalling/Bool/BoolTest.cs index 72b80c0c2b..29db00a81c 100644 --- a/tests/src/Interop/PrimitiveMarshalling/Bool/BoolTest.cs +++ b/tests/src/Interop/PrimitiveMarshalling/Bool/BoolTest.cs @@ -9,6 +9,9 @@ using System.Text; class Test { + const bool boolManaged = true; + const bool boolNative = false; + static void ReportFailure(string describe, bool expect, bool actual) { throw new Exception(" === Fail: " + describe + "\n\tExpected:" + expect + "\n\tActual:" + actual); @@ -16,12 +19,9 @@ class Test public static int Main(string[] args) { - const bool boolManaged = true; - const bool boolNative = false; - //Test Method1 bool boolValue1 = boolManaged; - bool boolValueRet1 = NativeMethods.Marshal_In(boolValue1); + bool boolValueRet1 = BoolNative.Marshal_In(boolValue1); if (!boolValueRet1) { ReportFailure("Method Marshal_In[Managed Side],The return value is wrong", true, boolValueRet1); @@ -29,7 +29,7 @@ class Test //TestMethod2 bool boolValue2 = boolManaged; - bool boolValueRet2 = NativeMethods.Marshal_InOut(boolValue2); + bool boolValueRet2 = BoolNative.Marshal_InOut(boolValue2); if (!boolValueRet2) { ReportFailure("Method Marshal_InOut[Managed Side],The return value is wrong", true, boolValueRet2); @@ -41,7 +41,7 @@ class Test //TestMethod3 bool boolValue3 = boolManaged; - bool boolValueRet3 = NativeMethods.Marshal_Out(boolValue3); + bool boolValueRet3 = BoolNative.Marshal_Out(boolValue3); if (!boolValueRet3) { ReportFailure("Method Marshal_Out[Managed Side],The return value is wrong", true, boolValueRet3); @@ -53,7 +53,7 @@ class Test //TestMethod4 bool boolValue4 = boolManaged; - bool boolValueRet4 = NativeMethods.MarshalPointer_In(ref boolValue4); + bool boolValueRet4 = BoolNative.MarshalPointer_In(ref boolValue4); if (!boolValueRet4) { ReportFailure("Method MarshalPointer_In[Managed Side],The return value is wrong", true, boolValueRet4); @@ -65,7 +65,7 @@ class Test //TestMethod5 bool boolValue5 = boolManaged; - bool boolValueRet5 = NativeMethods.MarshalPointer_InOut(ref boolValue5); + bool boolValueRet5 = BoolNative.MarshalPointer_InOut(ref boolValue5); if (!boolValueRet5) { ReportFailure("Method MarshalPointer_InOut[Managed Side],The return value is wrong", true, boolValueRet5); @@ -77,7 +77,7 @@ class Test //TestMethod6 bool boolValue6 = boolManaged; - bool boolValueRet6 = NativeMethods.MarshalPointer_Out(out boolValue6); + bool boolValueRet6 = BoolNative.MarshalPointer_Out(out boolValue6); if (!boolValueRet6) { ReportFailure("Method Marshal_Out[Managed Side],The return value is wrong", true, boolValueRet6); @@ -89,18 +89,18 @@ class Test //Test Method7 bool boolValue7 = boolManaged; - bool boolValueRet7 = NativeMethods.Marshal_As_In(boolValue7); + bool boolValueRet7 = BoolNative.Marshal_As_In(boolValue7); if (!boolValueRet7) { - ReportFailure("Method Marshal_As_In[Managed Side],The return value is wrong", true, boolValueRet1); + ReportFailure("Method Marshal_As_In[Managed Side],The return value is wrong", true, boolValueRet7); } //TestMethod8 bool boolValue8 = boolManaged; - bool boolValueRet8 = NativeMethods.Marshal_As_InOut(boolValue8); + bool boolValueRet8 = BoolNative.Marshal_As_InOut(boolValue8); if (!boolValueRet8) { - ReportFailure("Method Marshal_As_InOut[Managed Side],The return value is wrong", true, boolValueRet2); + ReportFailure("Method Marshal_As_InOut[Managed Side],The return value is wrong", true, boolValueRet8); } if (boolValue8 != boolManaged) { @@ -109,15 +109,83 @@ class Test //TestMethod9 bool boolValue9 = boolManaged; - bool boolValueRet9 = NativeMethods.Marshal_As_Out(boolValue9); + bool boolValueRet9 = BoolNative.Marshal_As_Out(boolValue9); if (!boolValueRet9) { - ReportFailure("Method Marshal_As_Out[Managed Side],The return value is wrong", true, boolValueRet3); + ReportFailure("Method Marshal_As_Out[Managed Side],The return value is wrong", true, boolValueRet9); } if (boolValue9 != boolManaged) { - ReportFailure("Method Marshal_As_Out[Managed Side],The parameter value is changed", boolManaged, boolValue3); + ReportFailure("Method Marshal_As_Out[Managed Side],The parameter value is changed", boolManaged, boolValue9); + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + TestVariantBool(); } + return 100; } + + private static void TestVariantBool() + { + + if (!BoolNative.Marshal_ByValue_Variant(true, true)) + { + ReportFailure("Method Marshal_ByValue_Variant[Managed Side], The return value is wrong", true, true); + } + + if (!BoolNative.Marshal_ByValue_Variant(false, false)) + { + ReportFailure("Method Marshal_ByValue_Variant[Managed Side], The return value is wrong", false, false); + } + + bool boolValue10 = boolManaged; + bool boolValueRet10 = BoolNative.Marshal_Ref_Variant(ref boolValue10); + + if (!boolValueRet10) + { + ReportFailure("Method Marshal_Ref_Variant[Managed Side], The return value is wrong.", true, boolValueRet10); + } + if (boolValue10 != boolNative) + { + ReportFailure("Method Marshal_Ref_Variant[Managed Side],The passed value is wrong", boolNative, boolValue10); + } + + var trueStruct = new BoolNative.ContainsVariantBool + { + value = true + }; + + var falseStruct = new BoolNative.ContainsVariantBool + { + value = false + }; + + if (!BoolNative.Marshal_ByValue_Struct_Variant(trueStruct, true)) + { + ReportFailure("Method Marshal_ByValue_Variant[Managed Side], The return value is wrong", true, true); + } + + if (!BoolNative.Marshal_ByValue_Struct_Variant(falseStruct, false)) + { + ReportFailure("Method Marshal_ByValue_Variant[Managed Side], The return value is wrong", false, false); + } + + var boolValue11 = new BoolNative.ContainsVariantBool + { + value = boolManaged + }; + + bool boolValueRet11 = BoolNative.Marshal_Ref_Struct_Variant(ref boolValue11); + + if (!boolValueRet11) + { + ReportFailure("Method Marshal_Ref_Variant[Managed Side], The return value is wrong.", true, boolValueRet11); + } + if (boolValue11.value != boolNative) + { + ReportFailure("Method Marshal_Ref_Variant[Managed Side],The passed value is wrong", boolNative, boolValue11.value); + } + } } diff --git a/tests/src/Interop/PrimitiveMarshalling/Bool/NativeMethodDef.cs b/tests/src/Interop/PrimitiveMarshalling/Bool/NativeMethodDef.cs index b46015fbd4..4d29f70d54 100644 --- a/tests/src/Interop/PrimitiveMarshalling/Bool/NativeMethodDef.cs +++ b/tests/src/Interop/PrimitiveMarshalling/Bool/NativeMethodDef.cs @@ -7,41 +7,69 @@ using System.Runtime.InteropServices; using System.Reflection; using System.Text; -public class NativeMethods +public class BoolNative { - - public const string NativeSharedBinaryName = "BoolNative"; - - [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)] + [DllImport(nameof(BoolNative))] public static extern bool Marshal_In([In]bool boolValue); - [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)] + [DllImport(nameof(BoolNative))] public static extern bool Marshal_InOut([In, Out]bool boolValue); - [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)] + [DllImport(nameof(BoolNative))] public static extern bool Marshal_Out([Out]bool boolValue); - [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)] + [DllImport(nameof(BoolNative))] public static extern bool MarshalPointer_In([In]ref bool pboolValue); - [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)] + [DllImport(nameof(BoolNative))] public static extern bool MarshalPointer_InOut(ref bool pboolValue); - [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)] + [DllImport(nameof(BoolNative))] public static extern bool MarshalPointer_Out(out bool pboolValue); - [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)] + [DllImport(nameof(BoolNative))] [return: MarshalAs(UnmanagedType.U1)] public static extern bool Marshal_As_In( [In, MarshalAs(UnmanagedType.U1)]bool boolValue); - [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)] + [DllImport(nameof(BoolNative))] [return: MarshalAs(UnmanagedType.U1)] public static extern bool Marshal_As_InOut( [In, Out, MarshalAs(UnmanagedType.U1)]bool boolValue); - [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)] + [DllImport(nameof(BoolNative))] [return: MarshalAs(UnmanagedType.U1)] public static extern bool Marshal_As_Out( [Out, MarshalAs(UnmanagedType.U1)]bool boolValue); + +#pragma warning disable CS0612, CS0618 + public struct ContainsVariantBool + { + [MarshalAs(UnmanagedType.VariantBool)] + public bool value; + } + + [DllImport(nameof(BoolNative))] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool Marshal_ByValue_Variant( + [MarshalAs(UnmanagedType.VariantBool)] bool value, + [MarshalAs(UnmanagedType.U1)] bool expected); + + [DllImport(nameof(BoolNative))] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool Marshal_Ref_Variant( + [MarshalAs(UnmanagedType.VariantBool)] ref bool value); + + [DllImport(nameof(BoolNative))] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool Marshal_ByValue_Struct_Variant( + ContainsVariantBool value, + [MarshalAs(UnmanagedType.U1)] bool expected); + + [DllImport(nameof(BoolNative))] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool Marshal_Ref_Struct_Variant(ref ContainsVariantBool value); + +#pragma warning restore CS0612, CS0618 + } |