Add tests for AsAny Marshalling (#20963)
authorJeremy Koritzinsky <jkoritzinsky@gmail.com>
Tue, 13 Nov 2018 22:13:57 +0000 (14:13 -0800)
committerGitHub <noreply@github.com>
Tue, 13 Nov 2018 22:13:57 +0000 (14:13 -0800)
* Copy over tests from .NET Framework.

* Convert tests to use CoreCLRTestLibrary. Clean up tests that weren't self-consistent.

* Pass in context for non best-fit-mapping tests.

* Move around/group declarations.

* Clean up typedef names/usage.

* Fix signedness.

* Use ptrdiff_t and size_t instead of C99 types.

* Fix printf specifiers

* Remove unneeded now duplicate typedef

tests/src/Interop/CMakeLists.txt
tests/src/Interop/PInvoke/AsAny/AsAnyNative.cpp [new file with mode: 0644]
tests/src/Interop/PInvoke/AsAny/AsAnyTest.cs [new file with mode: 0644]
tests/src/Interop/PInvoke/AsAny/AsAnyTest.csproj [new file with mode: 0644]
tests/src/Interop/PInvoke/AsAny/CMakeLists.txt [new file with mode: 0644]
tests/src/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h
tests/src/Interop/common/types.h

index 9c78b1d..dfae466 100644 (file)
@@ -18,6 +18,7 @@ add_subdirectory(PInvoke/Delegate/MarshalDelegateAsField)
 add_subdirectory(PInvoke/Delegate/MarshalDelegateAsParam)
 add_subdirectory(PInvoke/Primitives/Int)
 add_subdirectory(PInvoke/ExactSpelling)
+add_subdirectory(PInvoke/AsAny)
 add_subdirectory(NativeCallable)
 add_subdirectory(PrimitiveMarshalling/Bool)
 add_subdirectory(PrimitiveMarshalling/UIntPtr)
diff --git a/tests/src/Interop/PInvoke/AsAny/AsAnyNative.cpp b/tests/src/Interop/PInvoke/AsAny/AsAnyNative.cpp
new file mode 100644 (file)
index 0000000..3929ad7
--- /dev/null
@@ -0,0 +1,329 @@
+// 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>
+
+struct test1 {
+    LONG64 a;
+    LONG64 b;
+};
+
+extern "C" DLL_EXPORT LONG64 STDMETHODCALLTYPE PassLayout(test1* i) {
+    printf("PassLayout: i->a  = %lld\n", i->a);
+    printf("PassLayout: i->b = %lld\n", i->b);
+    return i->b;
+}
+
+
+struct AsAnyField
+{
+    int * intArray;
+};
+
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassUnicodeStr(LPCWSTR str)
+{
+       return (SHORT)str[0] == 0x0030 && (SHORT)str[1] == 0x7777 && (SHORT)str[2] == 0x000A;           
+}
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassAnsiStr(LPCSTR str , BOOL isIncludeUnMappableChar)
+{
+       if(isIncludeUnMappableChar)
+               return (BYTE)str[0] == 0x30 && (BYTE)str[1] == 0x3f && (BYTE)str[2] == 0x0A;
+       else
+               return (BYTE)str[0] == 0x30 && (BYTE)str[1] == 0x35 && (BYTE)str[2] == 0x0A;
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassUnicodeStrbd(LPCWSTR str)
+{
+       return (SHORT)str[0] == 0x0030 && (SHORT)str[1] == 0x7777 && (SHORT)str[2] == 0x000A;                   
+}
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassAnsiStrbd(LPCSTR str , BOOL isIncludeUnMappableChar)
+{
+       if(isIncludeUnMappableChar)
+               return (BYTE)str[0] == 0x30 && (BYTE)str[1] == 0x3f && (BYTE)str[2] == 0x0A;
+       else
+               return (BYTE)str[0] == 0x30 && (BYTE)str[1] == 0x35 && (BYTE)str[2] == 0x0A;
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassUnicodeCharArray(WCHAR CharArray_In [], WCHAR CharArray_InOut [], WCHAR CharArray_Out [])
+{
+       BOOL ret = FALSE;
+       ret = (SHORT)CharArray_In[0] == 0x0030 && (SHORT)CharArray_In[1] == 0x7777 && (SHORT)CharArray_In[2] == 0x000A 
+               && (SHORT)CharArray_InOut[0] == 0x0030 && (SHORT)CharArray_InOut[1] == 0x7777 && (SHORT)CharArray_InOut[2] == 0x000A ;
+
+       // revese the string for passing back
+       WCHAR temp = CharArray_InOut[0]; 
+
+       CharArray_InOut[0] = CharArray_InOut[2];
+       CharArray_Out[0] = CharArray_InOut[2];
+       CharArray_Out[1] = CharArray_InOut[1];
+       CharArray_InOut[2] = temp;
+       CharArray_Out[2] = temp;
+       return ret;
+}
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassAnsiCharArray(CHAR CharArray_In [], CHAR CharArray_InOut [], CHAR CharArray_Out [] ,
+        BOOL isIncludeUnMappableChar)
+{
+       BOOL ret = FALSE;
+       if(isIncludeUnMappableChar)
+               ret = (BYTE)CharArray_In[0] == 0x30 && (BYTE)CharArray_In[1] == 0x3f && (BYTE)CharArray_In[2] == 0x0A 
+                       && (BYTE)CharArray_InOut[0] == 0x30 && (BYTE)CharArray_InOut[1] == 0x3f && (BYTE)CharArray_InOut[2] == 0x0A;
+       else
+               ret = (BYTE)CharArray_In[0] == 0x30 && (BYTE)CharArray_In[1] == 0x35 && (BYTE)CharArray_In[2] == 0x0A 
+                       && (BYTE)CharArray_InOut[0] == 0x30 && (BYTE)CharArray_InOut[1] == 0x35 && (BYTE)CharArray_InOut[2] == 0x0A;
+
+       // reverse the string for passing back
+       CHAR temp = CharArray_InOut[0]; 
+
+       CharArray_InOut[0] = CharArray_InOut[2];
+       CharArray_Out[0] = CharArray_InOut[2];
+       CharArray_Out[1] = CharArray_InOut[1];
+       CharArray_InOut[2] = temp;
+       CharArray_Out[2] = temp;
+
+       return ret;
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArraySbyte(
+                       BYTE sbyteArray[], BYTE sbyteArray_In[], BYTE sbyteArray_InOut[], BYTE sbyteArray_Out[], BYTE expected[], int len){
+
+               for(int i = 0; i < len; i++)
+               {
+                       if(sbyteArray[i] != expected[i] || sbyteArray_In[i] != expected[i] || sbyteArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArraySbyte\n");
+                               return FALSE;
+                       }
+                       sbyteArray_InOut[i] = 10 + expected[i];
+                       sbyteArray_Out[i] = 10 + expected[i];
+               }
+               return TRUE;    
+}
+
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArrayByte(    
+               BYTE byteArray[], BYTE byteArray_In[], BYTE byteArray_InOut[], BYTE byteArray_Out[], BYTE expected[], int len){
+
+               for(int i = 0; i < len; i++)
+               {
+                       if(byteArray[i] != expected[i] || byteArray_In[i] != expected[i] || byteArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArrayByte\n");
+                               return FALSE;
+                       }
+                       byteArray_InOut[i] = 10 + expected[i];
+                       byteArray_Out[i] = 10 + expected[i];
+               }
+               return TRUE;    
+}
+    
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArrayShort(   
+               SHORT shortArray[], SHORT shortArray_In[], SHORT shortArray_InOut[], SHORT shortArray_Out[], SHORT expected[], int len){
+
+               for(int i = 0; i < len; i++)
+               {
+                       if(shortArray[i] != expected[i] || shortArray_In[i] != expected[i] || shortArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArrayShort\n");
+                               return FALSE;
+                       }
+                       shortArray_InOut[i] = 10 + expected[i];
+                       shortArray_Out[i] = 10 + expected[i];
+               }
+               return TRUE;    
+}
+    
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArrayUshort(  
+               USHORT ushortArray[], USHORT ushortArray_In[], USHORT ushortArray_InOut[], USHORT ushortArray_Out[], USHORT expected[], int len){
+
+               for(int i = 0; i < len; i++)
+               {
+                       if(ushortArray[i] != expected[i] || ushortArray_In[i] != expected[i] || ushortArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArrayUshort\n");
+                               return FALSE;
+                       }
+                       ushortArray_InOut[i] = 10 + expected[i];
+                       ushortArray_Out[i] = 10 + expected[i];
+               }
+               return TRUE;    
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArrayInt(     
+               int IntArray[], int IntArray_In[], int IntArray_InOut[], int IntArray_Out[], int expected[], int len){
+
+               for(int i = 0; i < len; i++)
+               {
+                       if(IntArray[i] != expected[i] || IntArray_In[i] != expected[i] || IntArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArrayInt\n");
+                               return FALSE;
+                       }
+                       IntArray_InOut[i] = 10 + expected[i];
+                       IntArray_Out[i] = 10 + expected[i];
+               }
+               return TRUE;    
+}
+
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArrayUint(    
+               UINT uintArray[], UINT uintArray_In[], UINT uintArray_InOut[], UINT uintArray_Out[], UINT expected[], int len){
+
+               for(int i = 0; i < len; i++)
+               {
+                       if(uintArray[i] != expected[i] || uintArray_In[i] != expected[i] || uintArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArrayUint\n");
+                               return FALSE;
+                       }
+                       uintArray_InOut[i] = 10 + expected[i];
+                       uintArray_Out[i] = 10 + expected[i];
+               }
+               return TRUE;    
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArrayLong(    
+               LONG64 longArray[], LONG64 longArray_In[], LONG64 longArray_InOut[], LONG64 longArray_Out[], LONG64 expected[], int len){
+
+               for(int i = 0; i < len; i++)
+               {
+                       if(longArray[i] != expected[i] || longArray_In[i] != expected[i] || longArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArrayLong\n");
+                               return FALSE;
+                       }
+                       longArray_InOut[i] = 10 + expected[i];
+                       longArray_Out[i] = 10 + expected[i];
+               }
+               return TRUE;    
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArrayUlong(   
+       LONG64 ulongArray[], LONG64 ulongArray_In[], LONG64 ulongArray_InOut[], 
+       LONG64 ulongArray_Out[], LONG64 expected[], int len){
+
+               for(int i = 0; i < len; i++)
+               {
+                       if(ulongArray[i] != expected[i] || ulongArray_In[i] != expected[i] || ulongArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArrayUlong\n");
+                               return FALSE;
+                       }
+                       ulongArray_InOut[i] = 10 + expected[i];
+                       ulongArray_Out[i] = 10 + expected[i];
+               }
+               return TRUE;  
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArraySingle(  
+       float singleArray[], float singleArray_In[], float singleArray_InOut[], 
+       float singleArray_Out[], float expected[], int len){
+
+               for(int i = 0; i < len; i++)
+               {
+                       if(singleArray[i] != expected[i] || singleArray_In[i] != expected[i] || singleArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArraySingle\n");
+                               return FALSE;
+                       }
+                       singleArray_InOut[i] = 10 + expected[i];
+                       singleArray_Out[i] = 10 + expected[i];
+               }
+               return TRUE;  
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArrayDouble(  
+       double doubleArray[], double doubleArray_In[], double doubleArray_InOut[], double doubleArray_Out[], double expected[], int len){
+
+               for(int i = 0; i < len; i++)
+               {
+                       if(doubleArray[i] != expected[i] || doubleArray_In[i] != expected[i] || doubleArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArrayDouble\n");
+                               return FALSE;
+                       }
+                       doubleArray_InOut[i] = 10 + expected[i];
+                       doubleArray_Out[i] = 10 + expected[i];
+               }
+               return TRUE;  
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArrayChar(    
+       CHAR charArray[], CHAR charArray_In[], CHAR charArray_InOut[], CHAR charArray_Out[], CHAR expected[], int len){
+               for(int i = 0; i < len; i++)
+               {
+                       if(charArray[i] != expected[i] || charArray_In[i] != expected[i] || charArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArrayChar\n");
+                               return FALSE;
+                       }                       
+               }
+               
+               charArray_InOut[0] = 100;
+               charArray_Out[0] = 100;
+               charArray_InOut[1] = 101;
+               charArray_Out[1] = 101;
+               charArray_InOut[2] = 102;
+               charArray_Out[2] = 102;
+
+               return TRUE;  
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArrayBool(    
+       BOOL boolArray[], BOOL boolArray_In[], BOOL boolArray_InOut[], BOOL boolArray_Out[], BOOL expected[], int len){
+
+               for(int i = 0; i < len; i++)
+               {
+                       if(boolArray[i] != expected[i] || boolArray_In[i] != expected[i] || boolArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArrayBool\n");
+                               return FALSE;
+                       }                       
+               }
+               
+               boolArray_InOut[0] = FALSE;
+               boolArray_Out[0] = FALSE;
+               boolArray_InOut[1] = TRUE;
+               boolArray_Out[1] = TRUE;
+               boolArray_InOut[2] = TRUE;
+               boolArray_Out[2] = TRUE;
+
+               return TRUE;  
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArrayIntPtr(  
+       INT_PTR intPtrArray[], INT_PTR intPtrArray_In[], INT_PTR intPtrArray_InOut[], INT_PTR intPtrArray_Out[], INT_PTR expected[], int len){
+
+               for(int i = 0; i < len; i++)
+               {
+                       if(intPtrArray[i] != expected[i] || intPtrArray_In[i] != expected[i] || intPtrArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArrayIntPtr\n");
+                               return FALSE;
+                       }
+                       intPtrArray_InOut[i] = 10 + expected[i];
+                       intPtrArray_Out[i] = 10 + expected[i];
+               }
+               return TRUE;  
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassArrayUIntPtr( 
+       UINT_PTR uIntPtrArray[], UINT_PTR uIntPtrArray_In[], UINT_PTR uIntPtrArray_InOut[], UINT_PTR uIntPtrArray_Out[], UINT_PTR expected[], int len){
+
+               for(int i = 0; i < len; i++)
+               {
+                       if(uIntPtrArray[i] != expected[i] || uIntPtrArray_In[i] != expected[i] || uIntPtrArray_InOut[i] != expected[i])
+                       {
+                               printf("Not correct pass in paremeter in PassArrayUIntPtr\n");
+                               return FALSE;
+                       }
+                       uIntPtrArray_InOut[i] = 10 + expected[i];
+                       uIntPtrArray_Out[i] = 10 + expected[i];
+               }
+               return TRUE;  
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE PassMixStruct(AsAnyField mix){
+               return TRUE;  
+}
diff --git a/tests/src/Interop/PInvoke/AsAny/AsAnyTest.cs b/tests/src/Interop/PInvoke/AsAny/AsAnyTest.cs
new file mode 100644 (file)
index 0000000..5a94721
--- /dev/null
@@ -0,0 +1,664 @@
+// 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.Threading;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.Reflection;
+using TestLibrary;
+
+#pragma warning disable CS0612, CS0618
+
+struct A
+{
+    public long a;
+    public long b;
+}
+
+struct AsAnyField
+{
+    [MarshalAs(UnmanagedType.AsAny)]
+    public object intArray;
+}
+
+class AsAnyTests
+{
+    private const char mappableChar = (char)0x2075;
+    private const char unmappableChar = (char)0x7777;
+    private const char NormalChar1 = '0';
+    private const char NormalChar2 = '\n';
+
+    private static readonly string MappableString = "" + NormalChar1 + mappableChar + NormalChar2;
+    private static readonly string UnmappableString = "" + NormalChar1 + unmappableChar + NormalChar2;
+        
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArraySbyte(
+        [MarshalAs(UnmanagedType.AsAny)] object sbyteArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object sbyteArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object sbyteArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object sbyteArray_Out,
+        sbyte[] expected,
+        int len
+    );
+    
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArrayByte(
+        [MarshalAs(UnmanagedType.AsAny)] object byteArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object byteArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object byteArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object byteArray_Out,
+        byte[] expected,
+        int len
+    );
+
+    //Short
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArrayShort(
+        [MarshalAs(UnmanagedType.AsAny)] object shortArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object shortArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object shortArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object shortArray_Out,
+        short[] expected,
+        int len
+    );
+
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArrayUshort(
+        [MarshalAs(UnmanagedType.AsAny)] object ushortArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object ushortArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object ushortArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object ushortArray_Out,
+        ushort[] expected,
+        int len
+    );
+
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArrayInt(
+        [MarshalAs(UnmanagedType.AsAny)] object intArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object intArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object intArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object intArray_Out,
+        int[] expected,
+        int len
+    );
+
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArrayUint(
+        [In, MarshalAs(UnmanagedType.AsAny)] object uintArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object uintArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object uintArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object uintArray_Out,
+        uint[] expected,
+        int len
+    );
+
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArrayLong(
+        [In, MarshalAs(UnmanagedType.AsAny)] object longArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object longArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object longArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object longArray_Out,
+        long[] expected,
+        int len
+    );
+
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArrayUlong(
+        [In, MarshalAs(UnmanagedType.AsAny)] object ulongArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object ulongArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object ulongArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object ulongArray_Out,
+        ulong[] expected,
+        int len
+    );
+
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArraySingle(
+        [In, MarshalAs(UnmanagedType.AsAny)] object singleArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object singleArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object singleArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object singleArray_Out,
+        float[] expected,
+        int len
+    );
+
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArrayDouble(
+        [In, MarshalAs(UnmanagedType.AsAny)] object doubleArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object doubleArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object doubleArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object doubleArray_Out,
+        double[] expected,
+        int len
+    );
+
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArrayChar(
+        [In, MarshalAs(UnmanagedType.AsAny)] object charArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object charArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object charArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object charArray_Out,
+        char[] expected,
+        int len
+    );
+
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArrayBool(
+        [In, MarshalAs(UnmanagedType.AsAny)] object boolArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object boolArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object boolArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object boolArray_Out,
+        bool[] expected,
+        int len
+    );
+
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArrayIntPtr(
+        [In, MarshalAs(UnmanagedType.AsAny)] object intPtrArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object intPtrArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object intPtrArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object intPtrArray_Out,
+        IntPtr[] expected,
+        int len
+    );
+
+    [DllImport("AsAnyNative")]
+    public static extern bool PassArrayUIntPtr(
+        [In, MarshalAs(UnmanagedType.AsAny)] object uIntPtrArray,
+        [In, MarshalAs(UnmanagedType.AsAny)] object uIntPtrArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object uIntPtrArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object uIntPtrArray_Out,
+        UIntPtr[] expected,
+        int len
+    );
+    
+    [DllImport("AsAnyNative")]
+    public static extern long PassLayout(
+    [MarshalAs(UnmanagedType.AsAny)] Object i);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassUnicodeStr", CharSet = CharSet.Unicode, 
+    BestFitMapping = true, ThrowOnUnmappableChar = true)]
+    public static extern bool PassUnicodeStrTT(
+    [MarshalAs(UnmanagedType.AsAny)]
+    Object i);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassUnicodeStr", CharSet = CharSet.Unicode,
+    BestFitMapping = false, ThrowOnUnmappableChar = true)]
+    public static extern bool PassUnicodeStrFT(
+    [MarshalAs(UnmanagedType.AsAny)]
+    Object i);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassUnicodeStr", CharSet = CharSet.Unicode,
+   BestFitMapping = false, ThrowOnUnmappableChar = false)]
+    public static extern bool PassUnicodeStrFF(                              
+    [MarshalAs(UnmanagedType.AsAny)]
+    Object i);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassAnsiStr", CharSet = CharSet.Ansi,
+    BestFitMapping = true, ThrowOnUnmappableChar = true)]
+    public static extern bool PassAnsiStrTT(
+    [MarshalAs(UnmanagedType.AsAny)]
+    Object i, bool isIncludeUnMappableChar);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassAnsiStr", CharSet = CharSet.Ansi,
+    BestFitMapping = false, ThrowOnUnmappableChar = true)]
+    public static extern bool PassAnsiStrFT(
+    [MarshalAs(UnmanagedType.AsAny)]
+    Object i, bool isIncludeUnMappableChar);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassAnsiStr", CharSet = CharSet.Ansi,
+    BestFitMapping = false, ThrowOnUnmappableChar = false)]
+    public static extern bool PassAnsiStrFF(
+    [MarshalAs(UnmanagedType.AsAny)]
+    Object i, bool isIncludeUnMappableChar);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassUnicodeStrbd", CharSet = CharSet.Unicode,
+    BestFitMapping = true, ThrowOnUnmappableChar = true)]
+    public static extern bool PassUnicodeStrbdTT(
+        [In, MarshalAs(UnmanagedType.AsAny)] object strbd_In);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassUnicodeStrbd", CharSet = CharSet.Unicode,
+    BestFitMapping = false, ThrowOnUnmappableChar = true)]
+    public static extern bool PassUnicodeStrbdFT(
+        [In, MarshalAs(UnmanagedType.AsAny)] object strbd_In);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassUnicodeStrbd", CharSet = CharSet.Unicode,
+   BestFitMapping = false, ThrowOnUnmappableChar = false)]
+    public static extern bool PassUnicodeStrbdFF(
+        [In, MarshalAs(UnmanagedType.AsAny)] object strbd_In);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassAnsiStrbd", CharSet = CharSet.Ansi,
+    BestFitMapping = true, ThrowOnUnmappableChar = true)]
+    public static extern bool PassAnsiStrbdTT(
+        [In, MarshalAs(UnmanagedType.AsAny)] object strbd_In,
+         bool isIncludeUnMappableChar);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassAnsiStrbd", CharSet = CharSet.Ansi,
+    BestFitMapping = false, ThrowOnUnmappableChar = true)]
+    public static extern bool PassAnsiStrbdFT(
+        [In, MarshalAs(UnmanagedType.AsAny)] object strbd_In,
+         bool isIncludeUnMappableChar);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassAnsiStrbd", CharSet = CharSet.Ansi,
+    BestFitMapping = false, ThrowOnUnmappableChar = false)]
+    public static extern bool PassAnsiStrbdFF(
+        [In, MarshalAs(UnmanagedType.AsAny)] object strbd_In,
+         bool isIncludeUnMappableChar);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassUnicodeCharArray", CharSet = CharSet.Unicode,
+    BestFitMapping = true, ThrowOnUnmappableChar = true)]
+    public static extern bool PassUnicodeCharArrayTT(
+        [In, MarshalAs(UnmanagedType.AsAny)] object CharArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object CharArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object CharArray_Out);
+
+
+    [DllImport("AsAnyNative", EntryPoint = "PassUnicodeCharArray", CharSet = CharSet.Unicode,
+    BestFitMapping = false, ThrowOnUnmappableChar = true)]
+    public static extern bool PassUnicodeCharArrayFT(
+        [In, MarshalAs(UnmanagedType.AsAny)] object CharArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object CharArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object CharArray_Out);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassUnicodeCharArray", CharSet = CharSet.Unicode,
+   BestFitMapping = false, ThrowOnUnmappableChar = false)]
+    public static extern bool PassUnicodeCharArrayFF(
+        [In, MarshalAs(UnmanagedType.AsAny)] object CharArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object CharArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object CharArray_Out);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassAnsiCharArray", CharSet = CharSet.Ansi,
+    BestFitMapping = true, ThrowOnUnmappableChar = true)]
+    public static extern bool PassAnsiCharArrayTT(
+        [In, MarshalAs(UnmanagedType.AsAny)] object CharArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object CharArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object CharArray_Out,
+        bool isIncludeUnMappableChar);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassAnsiCharArray", CharSet = CharSet.Ansi,
+    BestFitMapping = false, ThrowOnUnmappableChar = true)]
+    public static extern bool PassAnsiCharArrayFT(
+        [In, MarshalAs(UnmanagedType.AsAny)] object CharArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object CharArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object CharArray_Out,
+        bool isIncludeUnMappableChar);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassAnsiCharArray", CharSet = CharSet.Ansi,
+    BestFitMapping = false, ThrowOnUnmappableChar = false)]
+    public static extern bool PassAnsiCharArrayFF(
+        [In, MarshalAs(UnmanagedType.AsAny)] object CharArray_In,
+        [In, Out, MarshalAs(UnmanagedType.AsAny)] object CharArray_InOut,
+        [Out, MarshalAs(UnmanagedType.AsAny)] object CharArray_Out,
+        bool isIncludeUnMappableChar);
+
+    [DllImport("AsAnyNative", EntryPoint = "PassMixStruct")]
+    public static extern bool PassMixStruct(AsAnyField mix);
+
+    public static int Main()
+    {
+        try
+        {
+            TestSByteArray();
+            TestByteArray();
+            TestInt16Array();
+            TestUInt16Array();
+            TestInt32Array();
+            TestUInt32Array();
+            TestLongArray();
+            TestULongArray();
+            TestSingleArray();
+            TestDoubleArray();
+            TestCharArray();
+            TestBoolArray();
+            TestIntPtrArray();
+            TestUIntPtrArray();
+            TestLayout();
+            RunAsAnyFieldTests();
+            TestUnicodeString();
+            TestUnicodeStringArray();
+            TestUnicodeStringBuilder();
+            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+            {
+                RunBestFitMappingTests();
+            }
+        }
+        catch (Exception e)
+        {
+            Console.WriteLine(e);
+            return 101;
+        }
+        return 100;
+    }
+
+    private static void RunAsAnyFieldTests()
+    {
+        Assert.Throws<TypeLoadException>(() => PassMixStruct(new AsAnyField()));
+    }
+
+    private static void RunBestFitMappingTests()
+    {
+        TestAnsiStringBestFitMapping();
+        TestAnsiStringBuilder();
+        TestAnsiStringArrayBestFitMapping();
+    }
+
+    private static void TestAnsiStringArrayBestFitMapping()
+    {
+        string unMappableAnsiStr_back = "" + NormalChar2 + (char)0x003f + NormalChar1;
+        string mappableAnsiStr_back = "" + NormalChar2 + (char)0x0035 + NormalChar1;
+
+        char[] unMappableCharArray_In = new char[3];
+        char[] unMappableCharArray_InOut = new char[3];
+        char[] unMappableCharArray_Out = new char[3];
+        char[] mappableCharArray_In = new char[3];
+        char[] mappableCharArray_InOut = new char[3];
+        char[] mappableCharArray_Out = new char[3];
+
+        CharArrayInit(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out,
+           mappableCharArray_In, mappableCharArray_InOut, mappableCharArray_Out, UnmappableString, MappableString);
+        Assert.Throws<ArgumentException>(() => PassAnsiCharArrayTT(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out, true));
+
+        CharArrayInit(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out,
+           mappableCharArray_In, mappableCharArray_InOut, mappableCharArray_Out, UnmappableString, MappableString);
+        Assert.IsTrue(PassAnsiCharArrayTT(mappableCharArray_In, mappableCharArray_InOut, mappableCharArray_Out, false));
+        Assert.AreAllEqual(mappableAnsiStr_back.ToCharArray(), mappableCharArray_InOut);
+        Assert.AreAllEqual(mappableAnsiStr_back.ToCharArray(), mappableCharArray_Out);
+
+        CharArrayInit(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out,
+           mappableCharArray_In, mappableCharArray_InOut, mappableCharArray_Out, UnmappableString, MappableString);
+        Assert.Throws<ArgumentException>(() => PassAnsiCharArrayFT(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out, true));
+
+        CharArrayInit(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out,
+           mappableCharArray_In, mappableCharArray_InOut, mappableCharArray_Out, UnmappableString, MappableString);
+        Assert.Throws<ArgumentException>(() => PassAnsiCharArrayFT(mappableCharArray_In, mappableCharArray_InOut, mappableCharArray_Out, false));
+
+        CharArrayInit(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out,
+           mappableCharArray_In, mappableCharArray_InOut, mappableCharArray_Out, UnmappableString, MappableString);
+        Assert.IsTrue(PassAnsiCharArrayFF(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out, true));
+        Assert.AreAllEqual(unMappableAnsiStr_back.ToCharArray(), unMappableCharArray_InOut);
+        Assert.AreAllEqual(unMappableAnsiStr_back.ToCharArray(), unMappableCharArray_Out);
+    }
+
+    private static void TestUnicodeStringArray()
+    {
+        string unMappableUnicodeStr_back = "" + NormalChar2 + unmappableChar + NormalChar1;
+
+        char[] unMappableCharArray_In = new char[3];
+        char[] unMappableCharArray_InOut = new char[3];
+        char[] unMappableCharArray_Out = new char[3];
+        char[] mappableCharArray_In = new char[3];
+        char[] mappableCharArray_InOut = new char[3];
+        char[] mappableCharArray_Out = new char[3];
+
+        CharArrayInit(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out,
+            mappableCharArray_In, mappableCharArray_InOut, mappableCharArray_Out, UnmappableString, MappableString);
+        Assert.IsTrue(PassUnicodeCharArrayTT(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out));
+        Assert.AreAllEqual(unMappableUnicodeStr_back.ToCharArray(), unMappableCharArray_InOut);
+        Assert.AreAllEqual(unMappableUnicodeStr_back.ToCharArray(), unMappableCharArray_Out);
+
+        CharArrayInit(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out,
+            mappableCharArray_In, mappableCharArray_InOut, mappableCharArray_Out, UnmappableString, MappableString);
+        Assert.IsTrue(PassUnicodeCharArrayFT(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out));
+        Assert.AreAllEqual(unMappableUnicodeStr_back.ToCharArray(), unMappableCharArray_InOut);
+        Assert.AreAllEqual(unMappableUnicodeStr_back.ToCharArray(), unMappableCharArray_Out);
+
+        CharArrayInit(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out,
+            mappableCharArray_In, mappableCharArray_InOut, mappableCharArray_Out, UnmappableString, MappableString);
+        Assert.IsTrue(PassUnicodeCharArrayFF(unMappableCharArray_In, unMappableCharArray_InOut, unMappableCharArray_Out));
+        Assert.AreAllEqual(unMappableUnicodeStr_back.ToCharArray(), unMappableCharArray_InOut);
+        Assert.AreAllEqual(unMappableUnicodeStr_back.ToCharArray(), unMappableCharArray_Out);
+    }
+
+    private static void TestAnsiStringBuilder()
+    {
+        StringBuilder unMappableStrbd = new StringBuilder(UnmappableString);
+        StringBuilder mappableStrbd = new StringBuilder(MappableString);
+
+        Assert.Throws<ArgumentException>(() => PassAnsiStrbdTT(unMappableStrbd, true));
+        Assert.IsTrue(PassAnsiStrbdTT(mappableStrbd, false));
+        Assert.Throws<ArgumentException>(() => PassAnsiStrbdFT(unMappableStrbd, true));
+        Assert.Throws<ArgumentException>(() => PassAnsiStrbdFT(mappableStrbd, false));
+        Assert.IsTrue(PassAnsiStrbdFF(unMappableStrbd, true));
+    }
+
+    private static void TestUnicodeStringBuilder()
+    {
+        StringBuilder unMappableStrbd = new StringBuilder(UnmappableString);
+        Assert.IsTrue(PassUnicodeStrbdTT(unMappableStrbd));
+        Assert.IsTrue(PassUnicodeStrbdFT(unMappableStrbd));
+        Assert.IsTrue(PassUnicodeStrbdFF(unMappableStrbd));
+    }
+
+    private static void TestAnsiStringBestFitMapping()
+    {
+        Assert.Throws<ArgumentException>(() => PassAnsiStrTT(UnmappableString, true));
+        Assert.IsTrue(PassAnsiStrTT(MappableString, false));
+        Assert.Throws<ArgumentException>(() => PassAnsiStrFT(UnmappableString, true));
+        Assert.Throws<ArgumentException>(() => PassAnsiStrFT(MappableString, false));
+        Assert.IsTrue(PassAnsiStrFF(UnmappableString, true));
+    }
+
+    private static void TestUnicodeString()
+    {
+        Assert.IsTrue(PassUnicodeStrTT(UnmappableString));
+        Assert.IsTrue(PassUnicodeStrFT(UnmappableString));
+        Assert.IsTrue(PassUnicodeStrFF(UnmappableString));
+    }
+
+    private static void TestUIntPtrArray()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for UIntPtr array ");
+        UIntPtr[] uIntPtrArray = new UIntPtr[] { new UIntPtr(0), new UIntPtr(1), new UIntPtr(2) };
+        UIntPtr[] uIntPtrArray_In = new UIntPtr[] { new UIntPtr(0), new UIntPtr(1), new UIntPtr(2) };
+        UIntPtr[] uIntPtrArray_InOut = new UIntPtr[] { new UIntPtr(0), new UIntPtr(1), new UIntPtr(2) };
+        UIntPtr[] uIntPtrArray_Out = new UIntPtr[] { new UIntPtr(0), new UIntPtr(1), new UIntPtr(2) };
+        UIntPtr[] uIntPtrArray_Back = new UIntPtr[] { new UIntPtr(10), new UIntPtr(11), new UIntPtr(12) };
+        UIntPtr[] expected = new UIntPtr[] { new UIntPtr(0), new UIntPtr(1), new UIntPtr(2) };
+        Assert.IsTrue(PassArrayUIntPtr(uIntPtrArray, uIntPtrArray_In, uIntPtrArray_InOut, uIntPtrArray_Out, expected, 3));
+        Assert.AreAllEqual(uIntPtrArray_Back, uIntPtrArray_InOut);
+        Assert.AreAllEqual(uIntPtrArray_Back, uIntPtrArray_Out);
+    }
+
+    private static void TestIntPtrArray()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for IntPtr array ");
+        IntPtr[] intPtrArray = new IntPtr[] { new IntPtr(0), new IntPtr(1), new IntPtr(2) };
+        IntPtr[] intPtrArray_In = new IntPtr[] { new IntPtr(0), new IntPtr(1), new IntPtr(2) };
+        IntPtr[] intPtrArray_InOut = new IntPtr[] { new IntPtr(0), new IntPtr(1), new IntPtr(2) };
+        IntPtr[] intPtrArray_Out = new IntPtr[] { new IntPtr(0), new IntPtr(1), new IntPtr(2) };
+        IntPtr[] intPtrArray_Back = new IntPtr[] { new IntPtr(10), new IntPtr(11), new IntPtr(12) };
+        IntPtr[] expected = new IntPtr[] { new IntPtr(0), new IntPtr(1), new IntPtr(2) };
+        Assert.IsTrue(PassArrayIntPtr(intPtrArray, intPtrArray_In, intPtrArray_InOut, intPtrArray_Out, expected, 3));
+        Assert.AreAllEqual(intPtrArray_Back, intPtrArray_InOut);
+        Assert.AreAllEqual(intPtrArray_Back, intPtrArray_Out);
+    }
+
+    private static void TestBoolArray()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for bool array ");
+        bool[] boolArray = new bool[] { true, false, false };
+        bool[] boolArray_In = new bool[] { true, false, false };
+        bool[] boolArray_InOut = new bool[] { true, false, false };
+        bool[] boolArray_Out = new bool[] { true, false, false };
+        bool[] boolArray_Back = new bool[] { false, true, true };
+        Assert.IsTrue(PassArrayBool(boolArray, boolArray_In, boolArray_InOut, boolArray_Out, new bool[] { true, false, false }, 3));
+        Assert.AreAllEqual(boolArray_Back, boolArray_InOut);
+        Assert.AreAllEqual(boolArray_Back, boolArray_Out);
+    }
+
+    private static void TestCharArray()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for char array ");
+        char[] charArray = new char[] { 'a', 'b', 'c' };
+        char[] charArray_In = new char[] { 'a', 'b', 'c' };
+        char[] charArray_InOut = new char[] { 'a', 'b', 'c' };
+        char[] charArray_Out = new char[] { 'a', 'b', 'c' };
+        char[] charArray_Back = new char[] { 'd', 'e', 'f' };
+        Assert.IsTrue(PassArrayChar(charArray, charArray_In, charArray_InOut, charArray_Out, new char[] { 'a', 'b', 'c' }, 3));
+        Assert.AreAllEqual(charArray_Back, charArray_InOut);
+        Assert.AreAllEqual(charArray_Back, charArray_Out);
+    }
+
+    private static void TestDoubleArray()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for double array ");
+        double[] doubleArray = new double[] { 0.0, 1.1, 2.2 };
+        double[] doubleArray_In = new double[] { 0.0, 1.1, 2.2 };
+        double[] doubleArray_InOut = new double[] { 0.0, 1.1, 2.2 };
+        double[] doubleArray_Out = new double[] { 0.0, 1.1, 2.2 };
+        double[] doubleArray_Back = new double[] { 10.0, 11.1, 12.2 };
+        Assert.IsTrue(PassArrayDouble(doubleArray, doubleArray_In, doubleArray_InOut, doubleArray_Out, new double[] { 0.0, 1.1, 2.2 }, 3));
+        Assert.AreAllEqual(doubleArray_Back, doubleArray_InOut);
+        Assert.AreAllEqual(doubleArray_Back, doubleArray_Out);
+    }
+
+    private static void TestSingleArray()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for float array ");
+        float[] singleArray = new float[] { 0, 1, 2 };
+        float[] singleArray_In = new float[] { 0, 1, 2 };
+        float[] singleArray_InOut = new float[] { 0, 1, 2 };
+        float[] singleArray_Out = new float[] { 0, 1, 2 };
+        float[] singleArray_Back = new float[] { 10, 11, 12 };
+        Assert.IsTrue(PassArraySingle(singleArray, singleArray_In, singleArray_InOut, singleArray_Out, new float[] { 0, 1, 2 }, 3));
+        Assert.AreAllEqual(singleArray_Back, singleArray_InOut);
+        Assert.AreAllEqual(singleArray_Back, singleArray_Out);
+    }
+
+    private static void TestULongArray()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for ulong array ");
+        ulong[] ulongArray = new ulong[] { 0, 1, 2 };
+        ulong[] ulongArray_In = new ulong[] { 0, 1, 2 };
+        ulong[] ulongArray_InOut = new ulong[] { 0, 1, 2 };
+        ulong[] ulongArray_Out = new ulong[] { 0, 1, 2 };
+        ulong[] ulongArray_Back = new ulong[] { 10, 11, 12 };
+        Assert.IsTrue(PassArrayUlong(ulongArray, ulongArray_In, ulongArray_InOut, ulongArray_Out, new ulong[] { 0, 1, 2 }, 3));
+        Assert.AreAllEqual(ulongArray_Back, ulongArray_InOut);
+        Assert.AreAllEqual(ulongArray_Back, ulongArray_Out);
+    }
+
+    private static void TestLongArray()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for long array ");
+        long[] longArray = new long[] { 0, 1, 2 };
+        long[] longArray_In = new long[] { 0, 1, 2 };
+        long[] longArray_InOut = new long[] { 0, 1, 2 };
+        long[] longArray_Out = new long[] { 0, 1, 2 };
+        long[] longArray_Back = new long[] { 10, 11, 12 };
+        Assert.IsTrue(PassArrayLong(longArray, longArray_In, longArray_InOut, longArray_Out, new long[] { 0, 1, 2 }, 3));
+        Assert.AreAllEqual(longArray_Back, longArray_InOut);
+        Assert.AreAllEqual(longArray_Back, longArray_Out);
+    }
+
+    private static void TestUInt32Array()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for uint array ");
+        uint[] uintArray = new uint[] { 0, 1, 2 };
+        uint[] uintArray_In = new uint[] { 0, 1, 2 };
+        uint[] uintArray_InOut = new uint[] { 0, 1, 2 };
+        uint[] uintArray_Out = new uint[] { 0, 1, 2 };
+        uint[] uintArray_Back = new uint[] { 10, 11, 12 };
+        Assert.IsTrue(PassArrayUint(uintArray, uintArray_In, uintArray_InOut, uintArray_Out, new uint[] { 0, 1, 2 }, 3));
+        Assert.AreAllEqual(uintArray_Back, uintArray_InOut);
+        Assert.AreAllEqual(uintArray_Back, uintArray_Out);
+    }
+
+    private static void TestInt32Array()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for Int array ");
+        int[] intArray = new int[] { 0, 1, 2 };
+        int[] intArray_In = new int[] { 0, 1, 2 };
+        int[] intArray_InOut = new int[] { 0, 1, 2 };
+        int[] intArray_Out = new int[] { 0, 1, 2 };
+        int[] intArray_Back = new int[] { 10, 11, 12 };
+        Assert.IsTrue(PassArrayInt(intArray, intArray_In, intArray_InOut, intArray_Out, new int[] { 0, 1, 2 }, 3));
+        Assert.AreAllEqual(intArray_Back, intArray_InOut);
+        Assert.AreAllEqual(intArray_Back, intArray_Out);
+    }
+
+    private static void TestUInt16Array()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for ushort array ");
+        ushort[] ushortArray = new ushort[] { 0, 1, 2 };
+        ushort[] ushortArray_In = new ushort[] { 0, 1, 2 };
+        ushort[] ushortArray_InOut = new ushort[] { 0, 1, 2 };
+        ushort[] ushortArray_Out = new ushort[] { 0, 1, 2 };
+        ushort[] ushortArray_Back = new ushort[] { 10, 11, 12 };
+        Assert.IsTrue(PassArrayUshort(ushortArray, ushortArray_In, ushortArray_InOut, ushortArray_Out, new ushort[] { 0, 1, 2 }, 3));
+        Assert.AreAllEqual(ushortArray_Back, ushortArray_InOut);
+        Assert.AreAllEqual(ushortArray_Back, ushortArray_Out);
+    }
+
+    private static void TestInt16Array()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for short array ");
+        short[] shortArray = new short[] { -1, 0, 1 };
+        short[] shortArray_In = new short[] { -1, 0, 1 };
+        short[] shortArray_InOut = new short[] { -1, 0, 1 };
+        short[] shortArray_Out = new short[] { -1, 0, 1 };
+        short[] shortArray_Back = new short[] { 9, 10, 11 };
+        Assert.IsTrue(PassArrayShort(shortArray, shortArray_In, shortArray_InOut, shortArray_Out, new short[] { -1, 0, 1 }, 3));
+        Assert.AreAllEqual(shortArray_Back, shortArray_InOut);
+        Assert.AreAllEqual(shortArray_Back, shortArray_Out);
+    }
+
+    private static void TestByteArray()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for byte array ");
+        byte[] byteArray = new byte[] { 0, 1, 2 };
+        byte[] byteArray_In = new byte[] { 0, 1, 2 };
+        byte[] byteArray_InOut = new byte[] { 0, 1, 2 };
+        byte[] byteArray_Out = new byte[] { 0, 1, 2 };
+        byte[] byteArray_Back = new byte[] { 10, 11, 12 };
+        Assert.IsTrue(PassArrayByte(byteArray, byteArray_In, byteArray_InOut, byteArray_Out, new byte[] { 0, 1, 2 }, 3));
+        Assert.AreAllEqual(byteArray_Back, byteArray_InOut);
+        Assert.AreAllEqual(byteArray_Back, byteArray_Out);
+    }
+
+    private static void TestSByteArray()
+    {
+        Console.WriteLine("Scenario : Checking Marshal AsAny for sbyte array ");
+        sbyte[] sbyteArray = new sbyte[] { -1, 0, 1 };
+        sbyte[] sbyteArray_In = new sbyte[] { -1, 0, 1 };
+        sbyte[] sbyteArray_InOut = new sbyte[] { -1, 0, 1 };
+        sbyte[] sbyteArray_Out = new sbyte[] { -1, 0, 1 };
+        sbyte[] sbyteArray_Back = new sbyte[] { 9, 10, 11 };
+        Assert.IsTrue(PassArraySbyte(sbyteArray, sbyteArray_In, sbyteArray_InOut, sbyteArray_Out, new sbyte[] {-1, 0, 1}, 3));
+        Assert.AreAllEqual(sbyteArray_Back, sbyteArray_InOut);
+        Assert.AreAllEqual(sbyteArray_Back, sbyteArray_Out);
+    }
+
+    public static void TestLayout() {
+        Console.WriteLine("Scenario: Running Layout Tests:");
+        Console.WriteLine("------------------------");
+
+        A layoutStruct = new A
+        {
+            a = 12,
+            b = 3
+        };
+        
+        Assert.AreEqual(layoutStruct.b, PassLayout(layoutStruct));   
+        Console.WriteLine("------------------------");
+    }
+
+    static void CharArrayInit(char[] unMappableCharArray_In, char[] unMappableCharArray_InOut, char[] unMappableCharArray_Out,
+        char[] mappableCharArray_In, char[] mappableCharArray_InOut, char[] mappableCharArray_Out,
+        string unMappableStr, string mappableStr)
+    {
+        char[] u = unMappableStr.ToCharArray();
+        char[] m = mappableStr.ToCharArray();
+        for (int i = 0; i < 3; i++)
+        {
+            unMappableCharArray_In[i] = u[i];
+            unMappableCharArray_InOut[i] = u[i];
+            unMappableCharArray_Out[i] = u[i];
+            mappableCharArray_In[i] = m[i];
+            mappableCharArray_InOut[i] = m[i];
+            mappableCharArray_Out[i] = m[i];
+        }
+    }
+}
diff --git a/tests/src/Interop/PInvoke/AsAny/AsAnyTest.csproj b/tests/src/Interop/PInvoke/AsAny/AsAnyTest.csproj
new file mode 100644 (file)
index 0000000..bb7cc4e
--- /dev/null
@@ -0,0 +1,34 @@
+<?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" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <AssemblyName>AsAnyTest</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>
+    <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+  </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>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="CMakeLists.txt" />
+  </ItemGroup>
+  <Import Project="../../Interop.settings.targets" />
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Interop/PInvoke/AsAny/CMakeLists.txt b/tests/src/Interop/PInvoke/AsAny/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1c03bf3
--- /dev/null
@@ -0,0 +1,17 @@
+cmake_minimum_required (VERSION 2.6) 
+project (AsAnyNative) 
+include ("${CLR_INTEROP_TEST_ROOT}/Interop.cmake") 
+include_directories(${INC_PLATFORM_DIR}) 
+set(SOURCES 
+    AsAnyNative.cpp 
+) 
+if(WIN32)
+    list(APPEND LINK_LIBRARIES_ADDITIONAL
+        OleAut32.lib
+    )
+endif(WIN32)
+# add the executable 
+add_library (AsAnyNative SHARED ${SOURCES}) 
+target_link_libraries(AsAnyNative ${LINK_LIBRARIES_ADDITIONAL}) 
+# add the install targets 
+install (TARGETS AsAnyNative DESTINATION bin) 
index 0f04c84..befe246 100644 (file)
@@ -54,7 +54,6 @@ typedef unsigned short WORD;
 typedef short SHORT;
 typedef float FLOAT;
 typedef double DOUBLE;
-typedef long INT_PTR;
 #endif
 
 struct INNER2 // size = 12 bytes
index 1443e59..b4bbcde 100755 (executable)
@@ -5,6 +5,8 @@
 #ifndef _INTEROP_TYPES__H
 #define _INTEROP_TYPES__H
 
+#include <stddef.h>
+
 #undef INT_MIN
 #define INT_MIN           (-2147483647 - 1)
 
@@ -21,8 +23,8 @@ typedef unsigned error_t;
 typedef void* LPVOID;
 typedef unsigned char BYTE;
 typedef WCHAR OLECHAR;
-
-typedef unsigned int UINT_PTR;
+typedef ptrdiff_t INT_PTR;
+typedef size_t UINT_PTR;
 
 typedef unsigned long long ULONG64;
 typedef double DOUBLE;