summaryrefslogtreecommitdiff
path: root/tests/src
diff options
context:
space:
mode:
authortijoytom <tijoytom@users.noreply.github.com>2016-02-25 12:04:10 -0800
committertijoytom <tijoytom@users.noreply.github.com>2016-02-25 12:04:10 -0800
commit306a27c807b34593aa3f77bfd729c594e65a8845 (patch)
tree79dfcdf842f9e2449a252691c691d6958bdbeb98 /tests/src
parent97545d6f772546e4737c112007d687c6fbc640b4 (diff)
parentac71f8a8a4ed23bbcacb449537a8bce2053c9f29 (diff)
downloadcoreclr-306a27c807b34593aa3f77bfd729c594e65a8845.tar.gz
coreclr-306a27c807b34593aa3f77bfd729c594e65a8845.tar.bz2
coreclr-306a27c807b34593aa3f77bfd729c594e65a8845.zip
Merge pull request #3314 from tijoytom/master
Adding more interop tests.
Diffstat (limited to 'tests/src')
-rw-r--r--tests/src/Interop/ArrayMarshalling/BoolArray/CMakeLists.txt12
-rw-r--r--tests/src/Interop/ArrayMarshalling/BoolArray/MarshalBoolArrayNative.cpp236
-rw-r--r--tests/src/Interop/ArrayMarshalling/BoolArray/MarshalBoolArrayTest.cs274
-rw-r--r--tests/src/Interop/ArrayMarshalling/BoolArray/MarshalBoolArrayTest.csproj47
-rw-r--r--tests/src/Interop/ArrayMarshalling/BoolArray/project.json33
-rw-r--r--tests/src/Interop/ArrayMarshalling/ByValArray/CMakeLists.txt12
-rw-r--r--tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp599
-rw-r--r--tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValTest.cs1072
-rw-r--r--tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValTest.csproj48
-rw-r--r--tests/src/Interop/ArrayMarshalling/ByValArray/project.json33
-rw-r--r--tests/src/Interop/CMakeLists.txt8
-rw-r--r--tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp171
-rw-r--r--tests/src/Interop/PrimitiveMarshalling/Bool/BoolTest.cs119
-rw-r--r--tests/src/Interop/PrimitiveMarshalling/Bool/BoolTest.csproj49
-rw-r--r--tests/src/Interop/PrimitiveMarshalling/Bool/CMakeLists.txt17
-rw-r--r--tests/src/Interop/PrimitiveMarshalling/Bool/NativeMethodDef.cs43
-rw-r--r--tests/src/Interop/PrimitiveMarshalling/Bool/project.json33
-rw-r--r--tests/src/Interop/PrimitiveMarshalling/UIntPtr/CMakeLists.txt10
-rw-r--r--tests/src/Interop/PrimitiveMarshalling/UIntPtr/PInvokeUIntPtrTest.cs59
-rw-r--r--tests/src/Interop/PrimitiveMarshalling/UIntPtr/PInvokeUIntPtrTest.csproj49
-rw-r--r--tests/src/Interop/PrimitiveMarshalling/UIntPtr/UIntPtrNative.cpp86
-rw-r--r--tests/src/Interop/PrimitiveMarshalling/UIntPtr/project.json33
-rw-r--r--tests/src/Interop/common/Assertion.cs811
-rw-r--r--tests/src/Interop/common/types.h55
-rw-r--r--tests/src/Interop/common/xplatform.h190
25 files changed, 4099 insertions, 0 deletions
diff --git a/tests/src/Interop/ArrayMarshalling/BoolArray/CMakeLists.txt b/tests/src/Interop/ArrayMarshalling/BoolArray/CMakeLists.txt
new file mode 100644
index 0000000000..8cc5be3bed
--- /dev/null
+++ b/tests/src/Interop/ArrayMarshalling/BoolArray/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required (VERSION 2.6)
+project (MarshalBoolArrayNative)
+include_directories(${INC_PLATFORM_DIR})
+set(SOURCES MarshalBoolArrayNative.cpp)
+
+# add the executable
+add_library (MarshalBoolArrayNative SHARED ${SOURCES})
+
+# add the install targets
+install (TARGETS MarshalBoolArrayNative DESTINATION bin)
+
+
diff --git a/tests/src/Interop/ArrayMarshalling/BoolArray/MarshalBoolArrayNative.cpp b/tests/src/Interop/ArrayMarshalling/BoolArray/MarshalBoolArrayNative.cpp
new file mode 100644
index 0000000000..5fbfcc382f
--- /dev/null
+++ b/tests/src/Interop/ArrayMarshalling/BoolArray/MarshalBoolArrayNative.cpp
@@ -0,0 +1,236 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+#include <xplatform.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+const int iManaged = 10;
+const int iNative = 11;
+
+const int ArraySIZE = 5;
+
+
+//Rule for Passing Value
+// Reverse Pinvoke
+//M--->N true,true,true,true,true
+//N----M true,false,true,false,true
+
+//Reverse PInvoke
+//Pass by value
+typedef BOOL (__stdcall *CallBackIn)(int size,bool arr[]);
+extern "C" DLL_EXPORT BOOL DoCallBackIn(CallBackIn callback)
+{
+ //Init
+ bool * arr = (bool*)CoTaskMemAlloc(ArraySIZE);
+ for(int i = 0;i < ArraySIZE; i++ )
+ {
+ if( 0 == i%2)
+ {
+ arr[i] =true;
+ }
+ else
+ {
+ arr[i] = false;
+ }
+ }
+
+ if(!callback(ArraySIZE,arr))
+ {
+ printf("Native Side: in DoCallBackIn, The Callback return wrong value");
+ return false;
+ }
+
+ //Check the data
+ for(int i = 0;i < ArraySIZE; i++ )//Expected:true,false,true,false,true
+ {
+ if((0 == (i%2)) && !arr[i]) //expect true
+ {
+ printf("Native Side:Error in DoCallBackIn.The Item is %d\n",i+1);
+ CoTaskMemFree(arr);
+ return false;
+ }
+ else if((1 == (i%2))&&arr[i]) //expect false
+ {
+ printf("Native Side:Error in DoCallBackIn.The Item is %d\n",i+1);
+ CoTaskMemFree(arr);
+ return false;
+ }
+ }
+ CoTaskMemFree(arr);
+ return true;
+}
+
+typedef BOOL (__stdcall *CallBackOut)(int size,bool arr[]);
+extern "C" DLL_EXPORT BOOL DoCallBackOut(CallBackOut callback)
+{
+ bool * arr =(bool *)CoTaskMemAlloc(ArraySIZE);
+
+ if(!callback(ArraySIZE,arr))
+ {
+ printf("Native Side: in DoCallBackOut, The Callback return wrong value");
+ return FALSE;
+ }
+
+ //Check the data returnd from Managed Side
+ for(int i = 0;i < ArraySIZE; i++ )
+ {
+ if(!arr[i]) //expect true
+ {
+ printf("Native Side:Error in DoCallBackOut.The Item is %d\n",i+1);
+ CoTaskMemFree(arr);
+ return false;
+ }
+ }
+ CoTaskMemFree(arr);
+ return true;
+}
+
+typedef BOOL (__stdcall *CallBackInOut)(int size,bool arr[]);
+extern "C" DLL_EXPORT BOOL DoCallBackInOut(CallBackInOut callback)
+{
+ //Init
+ bool * arr =(bool *)CoTaskMemAlloc(ArraySIZE);
+ for(int i = 0;i < ArraySIZE; i++ )
+ {
+ if( 0 == i%2)
+ {
+ arr[i] = true;
+ }
+ else
+ {
+ arr[i] = false;
+ }
+ }
+
+ if(!callback(ArraySIZE,arr))
+ {
+ printf("Native Side: in DoCallBackInOut, The Callback return wrong value");
+
+ return FALSE;
+ }
+
+ //Check the data
+ for(int i = 0;i < ArraySIZE; i++ )
+ {
+ if(!arr[i]) //expect true
+ {
+ printf("Native Side:Error in DoCallBackInOut.The Item is %d\n",i+1);
+ CoTaskMemFree(arr);
+ return false;
+ }
+ }
+ CoTaskMemFree(arr);
+ return true;
+}
+
+
+//Reverse PInvoke
+//Pass by reference
+typedef BOOL (__stdcall *CallBackRefIn)(int size,bool ** arr);
+extern "C" DLL_EXPORT BOOL DoCallBackRefIn(CallBackRefIn callback)
+{
+ //Init:true,false,true,false,true
+ bool *parr = (bool *)CoTaskMemAlloc(ArraySIZE);
+
+ for(int i = 0;i < ArraySIZE;++i)
+ {
+ if( 0 == i%2)
+ {
+ parr[i] = true;
+ }
+ else
+ {
+ parr[i] = false;
+ }
+ }
+
+ if(!callback(ArraySIZE,&parr)) // &parr
+ {
+ printf("Native Side: in DoCallBackRefIn, The Callback return wrong value");
+ return FALSE;
+ }
+
+ //Check the data werent changed
+ for(int i = 0;i<ArraySIZE;++i)
+ {
+ if((0==(i%2)) && !parr[i]) //expect true
+ {
+ printf("Native Side:Error in DoCallBackInOut.The Item is %d\n",i+1);
+ CoTaskMemFree(parr);
+ return false;
+ }
+ else if((1==(i%2))&&parr[i]) //expect false
+ {
+ printf("Native Side:Error in DoCallBackInOut.The Item is %d\n",i+1);
+ CoTaskMemFree(parr);
+ return false;
+ }
+ }
+ CoTaskMemFree(parr);
+ return true;
+}
+
+typedef BOOL (__stdcall *CallBackRefOut)(int size,bool ** arr);
+extern "C" DLL_EXPORT BOOL DoCallBackRefOut(CallBackRefOut callback)
+{
+
+ bool* parr = NULL;
+
+ if(!callback(ArraySIZE,&parr))
+ {
+ printf("Native Side: in DoCallBackRefOut, The Callback return wrong value");
+ return FALSE;
+ }
+
+ //Check the data were changed to true,true
+ for(int i = 0;i<ArraySIZE;++i)
+ {
+ if(!(*(parr + i))) //expect true
+ {
+ printf("Native Side:Error in DoCallBackRefOut.The Item is %d\n",i+1);
+ CoTaskMemFree(parr);
+ return false;
+ }
+ }
+ CoTaskMemFree(parr);
+ return true;
+}
+
+typedef BOOL (__stdcall *CallBackRefInOut)(int size,bool ** arr);
+extern "C" DLL_EXPORT BOOL DoCallBackRefInOut(CallBackRefInOut callback)
+{
+ //Init,true,false,true,false
+ bool* parr = (bool*)CoTaskMemAlloc(ArraySIZE);
+ for(int i = 0;i<ArraySIZE;++i)
+ {
+ if( 0 == i%2)
+ {
+ parr[i] = true;
+ }
+ else
+ {
+ parr[i] = false;
+ }
+ }
+
+ if(!callback(ArraySIZE,&parr))
+ {
+ printf("Native Side: in DoCallBackRefInOut, The Callback return wrong value");
+ return FALSE;
+ }
+
+ //Check the data were changed to true,true
+ for(int i = 0;i<ArraySIZE;++i)
+ {
+ if(!(parr[i])) //expect true
+ {
+ printf("Native Side:Error in DoCallBackRefOut.The Item is %d\n",i+1);
+ CoTaskMemFree(parr);
+ return false;
+ }
+ }
+ CoTaskMemFree(parr);
+ return true;
+}
diff --git a/tests/src/Interop/ArrayMarshalling/BoolArray/MarshalBoolArrayTest.cs b/tests/src/Interop/ArrayMarshalling/BoolArray/MarshalBoolArrayTest.cs
new file mode 100644
index 0000000000..d6b1a8522d
--- /dev/null
+++ b/tests/src/Interop/ArrayMarshalling/BoolArray/MarshalBoolArrayTest.cs
@@ -0,0 +1,274 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+//
+// Adding tests for BoolArrayMarshaler code coverage
+//
+//Rule for Passing Value
+// Reverse Pinvoke
+//M--->N true,true,true,true,true
+//N----M true,false,true,false,true
+using System;
+using System.Text;
+using System.Security;
+using System.Runtime.InteropServices;
+using TestLibrary;
+
+public class MarshalBoolArray
+{
+ #region"variable"
+ const int SIZE = 5;
+ #endregion
+
+ #region "Reverse PInvoke"
+
+ #region "Bool Array"
+ [DllImport("MarshalBoolArrayNative")]
+ private static extern bool DoCallBackIn(CallBackIn callback);
+ private delegate bool CallBackIn([In]int size, [In, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeConst = SIZE)] bool[] array);
+ private static bool TestMethod_CallBackIn(int size, bool[] array)
+ {
+ bool retVal = true;
+
+ //Check the Input
+ if (SIZE != size)
+ {
+ retVal = false;
+ //TestFramework.LogError("001","Failed on the Managed Side:TestMethod_CallBackIn:Parameter Size is wrong");
+ }
+ for (int i = 0; i < SIZE; ++i) //Reverse PInvoke, true,false,true false,true
+ {
+ if ((0 == i % 2) && !array[i])
+ {
+ retVal = false;
+ //TestFramework.LogError("002","Failed on the Managed Side:TestMethod_CallBackIn. The " + (i + 1) + "st Item failed");
+ }
+ else if ((1 == i % 2) && array[i])
+ {
+ retVal = false;
+ //TestFramework.LogError("003","Failed on the Managed Side:TestMethod_CallBackIn. The " + (i + 1) + "st Item failed");
+ }
+ }
+ return retVal;
+ }
+
+ [DllImport("MarshalBoolArrayNative")]
+ private static extern bool DoCallBackOut(CallBackOut callback);
+ private delegate bool CallBackOut([In]int size, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeConst = SIZE)] bool[] array);
+ private static bool TestMethod_CallBackOut(int size, bool[] array)
+ {
+ bool retVal = true;
+ //Check the Input
+ if (SIZE != size)
+ {
+ retVal = false;
+ //TestFramework.LogError("004","Failed on the Managed Side:TestMethod_CallBackOut:Parameter Size is wrong");
+ }
+
+ for (int i = 0; i < SIZE; ++i) //Reverse PInvoke, true,true,true true,true
+ {
+ array[i] = true;
+ }
+ return retVal;
+ }
+
+ [DllImport("MarshalBoolArrayNative")]
+ private static extern bool DoCallBackInOut(CallBackInOut callback);
+ private delegate bool CallBackInOut([In]int size, [In, Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeConst = SIZE)] bool[] array);
+
+ private static bool TestMethod_CallBackInOut(int size, bool[] array)
+ {
+ bool retVal = true;
+ //Check the Input
+ if (SIZE != size)
+ {
+ retVal = false;
+ //TestFramework.LogError("005","Failed on the Managed Side:TestMethod_CallBackInOut:Parameter Size is wrong");
+ }
+ for (int i = 0; i < SIZE; ++i) //Reverse PInvoke, true,false,true false,true
+ {
+ if ((0 == i % 2) && !array[i])
+ {
+ retVal = false;
+ TestFramework.LogError("006","Failed on the Managed Side:TestMethod_CallBackInOut. The " + (i + 1) + "st Item failed");
+ }
+ else if ((1 == i % 2) && array[i])
+ {
+ retVal = false;
+ //TestFramework.LogError("007","Failed on the Managed Side:TestMethod_CallBackInOut. The " + (i + 1) + "st Item failed");
+ }
+ }
+
+ //Check the output
+ for (int i = 0; i < size; ++i) //Reverse PInvoke, true,true,true true,true
+ {
+ array[i] = true;
+ }
+ return retVal;
+ }
+ #endregion
+
+ #region"Bool Array Reference"
+ [DllImport("MarshalBoolArrayNative")]
+ private static extern bool DoCallBackRefIn(CallBackRefIn callback);
+ private delegate bool CallBackRefIn([In]int size, [In, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1)] ref bool[] array);
+
+ private static bool TestMethod_CallBackRefIn(int size, ref bool[] array)
+ {
+ bool retVal = true;
+ //Check the Input
+ if (SIZE != size)
+ {
+ retVal = false;
+ //TestFramework.LogError("008","Failed on the Managed Side:TestMethod_CallBackRefIn:Parameter Size is wrong");
+ }
+ //TODO: UnComment these line if the SizeConst attributes is support
+ //Since now the sizeconst doesnt support on ref,so only check the first item instead.
+ //Unhandled Exception: System.Runtime.InteropServices.MarshalDirectiveException: Cannot marshal 'parameter #2': Cannot use SizeParamIndex for ByRef array parameters.
+ //for (int i = 0; i < size; ++i) //Reverse PInvoke, true,false,true false,true
+ //{
+ // if ((0 == i % 2) && !array[i])
+ // {
+ // ReportFailure("Failed on the Managed Side:TestMethod_CallBackRefIn. The " + (i + 1) + "st Item failed", true.ToString(), false.ToString());
+ // }
+ // else if ((1 == i % 2) && array[i])
+ // {
+ // ReportFailure("Failed on the Managed Side:TestMethod_CallBackRefIn. The " + (i + 1) + "st Item failed", false.ToString(), true.ToString());
+ // }
+ // }
+ if (!array[0])
+ {
+ retVal = false;
+ //TestFramework.LogError("009","Failed on the Managed Side:TestMethod_CallBackRefIn. The first Item failed");
+ }
+ return retVal;
+ }
+
+
+
+ [DllImport("MarshalBoolArrayNative")]
+ private static extern bool DoCallBackRefOut(CallBackRefOut callback);
+ private delegate bool CallBackRefOut([In]int size, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1)] out bool[] array);
+
+ private static bool TestMethod_CallBackRefOut(int size, out bool[] array)
+ {
+ bool retVal = true;
+
+ //Check the Input
+ if (size != SIZE)
+ {
+ retVal = false;
+ //TestFramework.LogError("010","Failed on the Managed Side:TestMethod_CallBackRefOut:Parameter Size is wrong");
+ }
+
+ array = new bool[SIZE];
+ for (int i = 0; i < SIZE; ++i) //Reverse PInvoke, true,true,true true,true
+ {
+ array[i] = true;
+ }
+ return retVal;
+ }
+
+ [DllImport("MarshalBoolArrayNative")]
+ private static extern bool DoCallBackRefInOut(CallBackRefInOut callback);
+ private delegate bool CallBackRefInOut([In]int size, [In, Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1)] ref bool[] array);
+
+ private static bool TestMethod_CallBackRefInOut(int size, ref bool[] array)
+ {
+ bool retVal = true;
+ //Check the Input
+ if (SIZE != size)
+ {
+ retVal = false;
+ //TestFramework.LogError("011","Failed on the Managed Side:TestMethod_CallBackRefInOut:Parameter Size is wrong");
+ }
+ //TODO: UnComment these line if the SizeConst attributes is support
+ //Since now the sizeconst doesnt support on ref,so only check the first item instead.
+ //Unhandled Exception: System.Runtime.InteropServices.MarshalDirectiveException: Cannot marshal 'parameter #2': Cannot use SizeParamIndex for ByRef array parameters.
+ //for (int i = 0; i < size; ++i) //Reverse PInvoke, true,false,true false,true
+ //{
+ // if ((0 == i % 2) && !array[i])
+ // {
+ // ReportFailure("Failed on the Managed Side:TestMethod_CallBackRefInOut. The " + (i + 1) + "st Item failed", true.ToString(), false.ToString());
+ // }
+ // else if ((1 == i % 2) && array[i])
+ // {
+ // ReportFailure("Failed on the Managed Side:TestMethod_CallBackRefInOut. The " + (i + 1) + "st Item failed", false.ToString(), true.ToString());
+ // }
+ // }
+ if (!array[0])
+ {
+ retVal = false;
+ //TestFramework.LogError("012","Failed on the Managed Side:TestMethod_CallBackRefInOut. The first Item failed");
+ }
+
+ //Output
+ array = new bool[SIZE];
+ for (int i = 0; i < size; ++i) //Reverse PInvoke, true,true,true true,true
+ {
+ array[i] = true;
+ }
+ return retVal;
+ }
+ #endregion
+
+ #endregion
+
+ [System.Security.SecuritySafeCritical]
+ static int Main()
+ {
+ bool retVal = true;
+
+ //TestFramework.BeginScenario("Reverse PInvoke with In attribute");
+ if (!DoCallBackIn(new CallBackIn(TestMethod_CallBackIn)))
+ {
+ retVal = false;
+ //TestFramework.LogError("013","Error happens in Native side:DoCallBackIn");
+ }
+
+ //TestFramework.BeginScenario("Reverse PInvoke with Out attribute");
+ if (!DoCallBackOut(new CallBackOut(TestMethod_CallBackOut)))
+ {
+ retVal = false;
+ //TestFramework.LogError("014","Error happens in Native side:DoCallBackOut");
+ }
+
+ // TestFramework.BeginScenario("Reverse PInvoke with InOut attribute");
+ if (!DoCallBackInOut(new CallBackInOut(TestMethod_CallBackInOut)))
+ {
+ retVal = false;
+ TestFramework.LogError("015","Error happens in Native side:DoCallBackInOut");
+ }
+
+ // TestFramework.BeginScenario("Reverse PInvoke Reference In");
+ if (!DoCallBackRefIn(new CallBackRefIn(TestMethod_CallBackRefIn)))
+ {
+ retVal = false;
+ //TestFramework.LogError("016","Error happens in Native side:DoCallBackRefIn");
+ }
+
+ // TestFramework.BeginScenario("Reverse PInvoke Reference Out");
+ if (!DoCallBackRefOut(new CallBackRefOut(TestMethod_CallBackRefOut)))
+ {
+ retVal = false;
+ //TestFramework.LogError("017","Error happens in Native side:DoCallBackRefOut");
+ }
+
+ //TestFramework.BeginScenario("Reverse PInvoke Reference InOut");
+ if (!DoCallBackRefInOut(new CallBackRefInOut(TestMethod_CallBackRefInOut)))
+ {
+ retVal = false;
+ //TestFramework.LogError("019","Error happens in Native side:DoCallBackRefInOut");
+ }
+
+ if(retVal)
+ {
+ //Console.WriteLine("Succeeded!");
+ return 100;
+ }
+
+ throw new Exception("Failed");
+ // return 101;
+ }
+}
diff --git a/tests/src/Interop/ArrayMarshalling/BoolArray/MarshalBoolArrayTest.csproj b/tests/src/Interop/ArrayMarshalling/BoolArray/MarshalBoolArrayTest.csproj
new file mode 100644
index 0000000000..7d62022784
--- /dev/null
+++ b/tests/src/Interop/ArrayMarshalling/BoolArray/MarshalBoolArrayTest.csproj
@@ -0,0 +1,47 @@
+<?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>MarshalBoolArrayTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <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="MarshalBoolArrayTest.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj">
+ <Project>{c8c0dc74-fac4-45b1-81fe-70c4808366e0}</Project>
+ <Name>CoreCLRTestLibrary</Name>
+ </ProjectReference>
+ <ProjectReference Include="CMakeLists.txt" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Interop/ArrayMarshalling/BoolArray/project.json b/tests/src/Interop/ArrayMarshalling/BoolArray/project.json
new file mode 100644
index 0000000000..cd536cf30e
--- /dev/null
+++ b/tests/src/Interop/ArrayMarshalling/BoolArray/project.json
@@ -0,0 +1,33 @@
+{
+ "dependencies": {
+ "System.Diagnostics.Process": "4.0.0-beta-23302",
+ "System.IO": "4.0.10-beta-23302",
+ "System.IO.FileSystem": "4.0.0-beta-23302",
+ "System.IO.FileSystem.Primitives": "4.0.0-beta-23302",
+ "System.Runtime": "4.0.20-beta-23302",
+ "System.Runtime.Extensions": "4.0.10-beta-23302",
+ "System.Runtime.Handles": "4.0.0-beta-23302",
+ "System.Runtime.Loader": "4.0.0-beta-23302",
+ "System.Threading": "4.0.10-beta-23302",
+ "System.Globalization.Calendars": "4.0.0-beta-23302",
+ "System.Globalization": "4.0.10-beta-23302",
+ "System.Text.Encoding": "4.0.10-beta-23302",
+ "System.Runtime.InteropServices": "4.0.20-beta-23302",
+ "System.Collections": "4.0.10-beta-23302",
+ "System.Console": "4.0.0-beta-23302",
+ "System.Reflection": "4.0.10-beta-23302",
+ "System.Reflection.Primitives": "4.0.0-beta-23302",
+ "System.ComponentModel": "4.0.1-beta-23302",
+ "System.Xml.ReaderWriter": "4.0.11-beta-23302",
+ "System.Collections.NonGeneric": "4.0.1-beta-23302",
+ "System.Collections.Specialized": "4.0.1-beta-23302",
+ "System.Linq": "4.0.1-beta-23302",
+ "System.Linq.Queryable": "4.0.1-beta-23302",
+ "System.Xml.XmlSerializer": "4.0.11-beta-23302",
+ "System.Xml.XmlDocument": "4.0.1-beta-23302",
+ "System.Xml.XDocument": "4.0.11-beta-23302"
+ },
+ "frameworks": {
+ "dnxcore50": {}
+ }
+} \ No newline at end of file
diff --git a/tests/src/Interop/ArrayMarshalling/ByValArray/CMakeLists.txt b/tests/src/Interop/ArrayMarshalling/ByValArray/CMakeLists.txt
new file mode 100644
index 0000000000..9c13ce0526
--- /dev/null
+++ b/tests/src/Interop/ArrayMarshalling/ByValArray/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required (VERSION 2.6)
+project (MarshalArrayByValNative)
+include_directories(${INC_PLATFORM_DIR})
+set(SOURCES MarshalArrayByValNative.cpp)
+
+# add the executable
+add_library (MarshalArrayByValNative SHARED ${SOURCES})
+
+# add the install targets
+install (TARGETS MarshalArrayByValNative DESTINATION bin)
+
+
diff --git a/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp b/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp
new file mode 100644
index 0000000000..78086f953a
--- /dev/null
+++ b/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp
@@ -0,0 +1,599 @@
+
+#include <xplatform.h>
+
+const int ARRAY_SIZE = 100;
+template<typename T> bool IsObjectEquals(T o1, T o2);
+
+/*----------------------------------------------------------------------------
+macro definition
+----------------------------------------------------------------------------*/
+
+#define ENTERFUNC() printf("========== [%s]\t ==========\n", __FUNCTION__)
+
+#define CHECK_PARAM_NOT_EMPTY(__p) \
+ ENTERFUNC(); \
+ if ( (__p) == NULL ) \
+{ \
+ printf("[%s] Error: parameter actual is NULL\n", __FUNCTION__); \
+ return false; \
+} \
+ else
+
+#define INIT_EXPECTED(__type, __size) \
+ __type expected[(__size)]; \
+ for ( size_t i = 0; i < (__size); ++i) \
+ expected[i] = (__type)i
+
+#define INIT_EXPECTED_STRUCT(__type, __size, __array_type) \
+ __type *expected = (__type *)::CoTaskMemAlloc( sizeof(__type) ); \
+ for ( size_t i = 0; i < (__size); ++i) \
+ expected->arr[i] = (__array_type)i
+
+#define EQUALS(__actual, __cActual, __expected) Equals((__actual), (__cActual), (__expected), (int)sizeof(__expected) / sizeof(__expected[0]))
+
+/*----------------------------------------------------------------------------
+struct definition
+----------------------------------------------------------------------------*/
+
+typedef struct { INT arr[ARRAY_SIZE]; } S_INTArray;
+typedef struct { UINT arr[ARRAY_SIZE]; } S_UINTArray;
+typedef struct { SHORT arr[ARRAY_SIZE]; } S_SHORTArray;
+typedef struct { WORD arr[ARRAY_SIZE]; } S_WORDArray;
+typedef struct { LONG64 arr[ARRAY_SIZE]; } S_LONG64Array;
+
+typedef struct { ULONG64 arr[ARRAY_SIZE]; } S_ULONG64Array;
+typedef struct { DOUBLE arr[ARRAY_SIZE]; } S_DOUBLEArray;
+typedef struct { FLOAT arr[ARRAY_SIZE]; } S_FLOATArray;
+typedef struct { BYTE arr[ARRAY_SIZE]; } S_BYTEArray;
+typedef struct { CHAR arr[ARRAY_SIZE]; } S_CHARArray;
+
+typedef struct { DWORD_PTR arr[ARRAY_SIZE]; } S_DWORD_PTRArray;
+
+typedef struct { LPSTR arr[ARRAY_SIZE]; } S_LPSTRArray;
+typedef struct { LPCSTR arr[ARRAY_SIZE]; } S_LPCSTRArray;
+
+//struct array in a struct
+typedef struct { INT x; DOUBLE d;
+LONG64 l; LPSTR str; } TestStruct;
+
+typedef struct { TestStruct arr[ARRAY_SIZE]; } S_StructArray;
+
+typedef struct { BOOL arr[ARRAY_SIZE]; } S_BOOLArray;
+
+/*----------------------------------------------------------------------------
+helper function
+----------------------------------------------------------------------------*/
+
+
+LPSTR ToString(int i)
+{
+ CHAR *pBuffer = (CHAR *)::CoTaskMemAlloc(10 * sizeof(CHAR)); // 10 is enough for our case, WCHAR for BSTR
+ snprintf(pBuffer, 10 * sizeof(CHAR), "%d", i);
+ return pBuffer;
+}
+
+
+
+TestStruct* InitTestStruct()
+{
+ TestStruct *expected = (TestStruct *)CoTaskMemAlloc( sizeof(TestStruct) * ARRAY_SIZE );
+
+ for ( size_t i = 0; i < ARRAY_SIZE; i++)
+ {
+ expected[i].x = i;
+ expected[i].d = i;
+ expected[i].l = i;
+ expected[i].str = ToString(i);
+ }
+
+ return expected;
+}
+
+template<typename T>
+BOOL Equals(T *pActual, int cActual, T *pExpected, int cExpected)
+{
+ if ( pActual == NULL && pExpected == NULL )
+ return TRUE;
+ else if ( cActual != cExpected )
+ {
+ printf("WARNING: Test error - %s\n", __FUNCSIG__);
+ return FALSE;
+ }
+
+ for ( size_t i = 0; i < ((size_t) cExpected); ++i )
+ {
+ if ( !IsObjectEquals(pActual[i], pExpected[i]) )
+ {
+ printf("WARNING: Test error - %s\n", __FUNCSIG__);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+template<typename T> bool IsObjectEquals(T o1, T o2)
+{
+ // T::operator== required.
+ return o1 == o2;
+}
+
+template<>
+bool IsObjectEquals(LPSTR o1, LPSTR o2)
+{
+ int cLen1 = strlen(o1);
+ int cLen2 = strlen(o2);
+
+ if (cLen1 != cLen2 )
+ {
+ printf("Not equals in %s\n",__FUNCTION__);
+ return false;
+ }
+
+ return strncmp(o1, o2, cLen1) == 0;
+}
+
+template<>
+bool IsObjectEquals(LPCSTR o1, LPCSTR o2)
+{
+ int cLen1 = strlen(o1);
+ int cLen2 = strlen(o2);
+
+ if (cLen1 != cLen2 )
+ {
+ printf("Not equals in %s\n",__FUNCTION__);
+ return false;
+ }
+
+ return strncmp(o1, o2, cLen1) == 0;
+}
+
+
+bool TestStructEquals(TestStruct Actual[], TestStruct Expected[])
+{
+ if ( Actual == NULL && Expected == NULL )
+ return true;
+ else if ( Actual == NULL && Expected != NULL )
+ return false;
+ else if ( Actual != NULL && Expected == NULL )
+ return false;
+
+ for ( size_t i = 0; i < ARRAY_SIZE; ++i )
+ {
+ if ( !(IsObjectEquals(Actual[i].x, Expected[i].x) &&
+ IsObjectEquals(Actual[i].d, Expected[i].d) &&
+ IsObjectEquals(Actual[i].l, Expected[i].l) &&
+ IsObjectEquals(Actual[i].str, Expected[i].str) ))
+ {
+ printf("WARNING: Test error - %s\n", __FUNCSIG__);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*----------------------------------------------------------------------------
+
+Function
+
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+marshal sequential strut
+----------------------------------------------------------------------------*/
+extern "C" DLL_EXPORT BOOL TakeIntArraySeqStructByVal( S_INTArray s, int size )
+{
+ CHECK_PARAM_NOT_EMPTY( s.arr );
+ INIT_EXPECTED( INT, ARRAY_SIZE );
+ return Equals( s.arr, size, expected, ARRAY_SIZE );
+}
+
+extern "C" DLL_EXPORT BOOL TakeUIntArraySeqStructByVal( S_UINTArray s, int size )
+{
+ CHECK_PARAM_NOT_EMPTY( s.arr );
+ INIT_EXPECTED( UINT, ARRAY_SIZE );
+ return Equals( s.arr, size, expected, ARRAY_SIZE );
+}
+
+extern "C" DLL_EXPORT BOOL TakeShortArraySeqStructByVal( S_SHORTArray s, int size )
+{
+ CHECK_PARAM_NOT_EMPTY( s.arr );
+ INIT_EXPECTED( SHORT, ARRAY_SIZE );
+ return Equals( s.arr, size, expected, ARRAY_SIZE );
+}
+
+extern "C" DLL_EXPORT BOOL TakeWordArraySeqStructByVal( S_WORDArray s, int size )
+{
+ CHECK_PARAM_NOT_EMPTY( s.arr );
+ INIT_EXPECTED( WORD, ARRAY_SIZE );
+ return Equals( s.arr, size, expected, ARRAY_SIZE );
+}
+
+extern "C" DLL_EXPORT BOOL TakeLong64ArraySeqStructByVal( S_LONG64Array s, int size )
+{
+ CHECK_PARAM_NOT_EMPTY( s.arr );
+ INIT_EXPECTED( LONG64, ARRAY_SIZE );
+ return Equals( s.arr, size, expected, ARRAY_SIZE );
+}
+
+extern "C" DLL_EXPORT BOOL TakeULong64ArraySeqStructByVal( S_ULONG64Array s, int size )
+{
+ CHECK_PARAM_NOT_EMPTY( s.arr );
+ INIT_EXPECTED( ULONG64, ARRAY_SIZE );
+ return Equals( s.arr, size, expected, ARRAY_SIZE );
+}
+
+extern "C" DLL_EXPORT BOOL TakeDoubleArraySeqStructByVal( S_DOUBLEArray s, int size )
+{
+ CHECK_PARAM_NOT_EMPTY( s.arr );
+ INIT_EXPECTED( DOUBLE, ARRAY_SIZE );
+ return Equals( s.arr, size, expected, ARRAY_SIZE );
+}
+
+extern "C" DLL_EXPORT BOOL TakeFloatArraySeqStructByVal( S_FLOATArray s, int size )
+{
+ CHECK_PARAM_NOT_EMPTY( s.arr );
+ INIT_EXPECTED( FLOAT, ARRAY_SIZE );
+ return Equals( s.arr, size, expected, ARRAY_SIZE );
+}
+
+extern "C" DLL_EXPORT BOOL TakeByteArraySeqStructByVal( S_BYTEArray s, int size )
+{
+ CHECK_PARAM_NOT_EMPTY( s.arr );
+ INIT_EXPECTED( BYTE, ARRAY_SIZE );
+ return Equals( s.arr, size, expected, ARRAY_SIZE );
+}
+
+extern "C" DLL_EXPORT BOOL TakeCharArraySeqStructByVal( S_CHARArray s, int size )
+{
+ CHECK_PARAM_NOT_EMPTY( s.arr );
+ INIT_EXPECTED( CHAR, ARRAY_SIZE );
+ return Equals( s.arr, size, expected, ARRAY_SIZE );
+}
+
+extern "C" DLL_EXPORT BOOL TakeIntPtrArraySeqStructByVal(S_DWORD_PTRArray s, int size)
+{
+ CHECK_PARAM_NOT_EMPTY(s.arr);
+ INIT_EXPECTED( DWORD_PTR, ARRAY_SIZE);
+ return Equals(s.arr, size, expected, ARRAY_SIZE);
+}
+
+extern "C" DLL_EXPORT BOOL TakeLPSTRArraySeqStructByVal( S_LPSTRArray s, int size )
+{
+ CHECK_PARAM_NOT_EMPTY( s.arr );
+
+ LPSTR expected[ARRAY_SIZE];
+ for ( size_t i = 0; i < ARRAY_SIZE; ++i )
+ expected[i] = ToString(i);
+
+ return Equals( s.arr, size, expected, ARRAY_SIZE );
+}
+
+extern "C" DLL_EXPORT BOOL TakeLPCSTRArraySeqStructByVal( S_LPCSTRArray s, int size )
+{
+ CHECK_PARAM_NOT_EMPTY( s.arr );
+
+ LPSTR expected[ARRAY_SIZE];
+ for ( size_t i = 0; i < ARRAY_SIZE; ++i )
+ expected[i] = ToString(i);
+
+ return Equals( s.arr, size, (LPCSTR *)expected, ARRAY_SIZE );
+}
+
+
+
+extern "C" DLL_EXPORT BOOL TakeStructArraySeqStructByVal( S_StructArray s, int size )
+{
+ CHECK_PARAM_NOT_EMPTY( s.arr );
+
+ TestStruct *expected = InitTestStruct();
+ return TestStructEquals( s.arr,expected );
+}
+
+/*----------------------------------------------------------------------------
+marshal sequential class
+----------------------------------------------------------------------------*/
+extern "C" DLL_EXPORT BOOL TakeIntArraySeqClassByVal( S_INTArray *s, int size )
+{
+ return TakeIntArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeUIntArraySeqClassByVal( S_UINTArray *s, int size )
+{
+ return TakeUIntArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeShortArraySeqClassByVal( S_SHORTArray *s, int size )
+{
+ return TakeShortArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeWordArraySeqClassByVal( S_WORDArray *s, int size )
+{
+ return TakeWordArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeLong64ArraySeqClassByVal( S_LONG64Array *s, int size )
+{
+ return TakeLong64ArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeULong64ArraySeqClassByVal( S_ULONG64Array *s, int size )
+{
+ return TakeULong64ArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeDoubleArraySeqClassByVal( S_DOUBLEArray *s, int size )
+{
+ return TakeDoubleArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeFloatArraySeqClassByVal( S_FLOATArray *s, int size )
+{
+ return TakeFloatArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeByteArraySeqClassByVal( S_BYTEArray *s, int size )
+{
+ return TakeByteArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeCharArraySeqClassByVal( S_CHARArray *s, int size )
+{
+ return TakeCharArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeLPSTRArraySeqClassByVal( S_LPSTRArray *s, int size )
+{
+ return TakeLPSTRArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeLPCSTRArraySeqClassByVal( S_LPCSTRArray *s, int size )
+{
+ return TakeLPCSTRArraySeqStructByVal( *s, size );
+}
+
+
+
+extern "C" DLL_EXPORT BOOL TakeStructArraySeqClassByVal( S_StructArray *s, int size )
+{
+ return TakeStructArraySeqStructByVal( *s, size );
+}
+
+/*----------------------------------------------------------------------------
+marshal explicit struct
+----------------------------------------------------------------------------*/
+extern "C" DLL_EXPORT BOOL TakeIntArrayExpStructByVal( S_INTArray s, int size )
+{
+ return TakeIntArraySeqStructByVal( s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeUIntArrayExpStructByVal( S_UINTArray s, int size )
+{
+ return TakeUIntArraySeqStructByVal( s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeShortArrayExpStructByVal( S_SHORTArray s, int size )
+{
+ return TakeShortArraySeqStructByVal( s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeWordArrayExpStructByVal( S_WORDArray s, int size )
+{
+ return TakeWordArraySeqStructByVal( s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeLong64ArrayExpStructByVal( S_LONG64Array s, int size )
+{
+ return TakeLong64ArraySeqStructByVal( s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeULong64ArrayExpStructByVal( S_ULONG64Array s, int size )
+{
+ return TakeULong64ArraySeqStructByVal( s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeDoubleArrayExpStructByVal( S_DOUBLEArray s, int size )
+{
+ return TakeDoubleArraySeqStructByVal( s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeFloatArrayExpStructByVal( S_FLOATArray s, int size )
+{
+ return TakeFloatArraySeqStructByVal( s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeByteArrayExpStructByVal( S_BYTEArray s, int size )
+{
+ return TakeByteArraySeqStructByVal( s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeCharArrayExpStructByVal( S_CHARArray s, int size )
+{
+ return TakeCharArraySeqStructByVal( s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeLPSTRArrayExpStructByVal( S_LPSTRArray s, int size )
+{
+ return TakeLPSTRArraySeqStructByVal( s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeLPCSTRArrayExpStructByVal( S_LPCSTRArray s, int size )
+{
+ return TakeLPCSTRArraySeqStructByVal( s, size );
+}
+
+
+
+extern "C" DLL_EXPORT BOOL TakeStructArrayExpStructByVal( S_StructArray s, int size )
+{
+ return TakeStructArraySeqStructByVal( s, size );
+}
+
+/*----------------------------------------------------------------------------
+marshal explicit class
+----------------------------------------------------------------------------*/
+extern "C" DLL_EXPORT BOOL TakeIntArrayExpClassByVal( S_INTArray *s, int size )
+{
+ return TakeIntArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeUIntArrayExpClassByVal( S_UINTArray *s, int size )
+{
+ return TakeUIntArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeShortArrayExpClassByVal( S_SHORTArray *s, int size )
+{
+ return TakeShortArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeWordArrayExpClassByVal( S_WORDArray *s, int size )
+{
+ return TakeWordArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeLong64ArrayExpClassByVal( S_LONG64Array *s, int size )
+{
+ return TakeLong64ArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeULong64ArrayExpClassByVal( S_ULONG64Array *s, int size )
+{
+ return TakeULong64ArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeDoubleArrayExpClassByVal( S_DOUBLEArray *s, int size )
+{
+ return TakeDoubleArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeFloatArrayExpClassByVal( S_FLOATArray *s, int size )
+{
+ return TakeFloatArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeByteArrayExpClassByVal( S_BYTEArray *s, int size )
+{
+ return TakeByteArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeCharArrayExpClassByVal( S_CHARArray *s, int size )
+{
+ return TakeCharArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeLPSTRArrayExpClassByVal( S_LPSTRArray *s, int size )
+{
+ return TakeLPSTRArraySeqStructByVal( *s, size );
+}
+
+extern "C" DLL_EXPORT BOOL TakeLPCSTRArrayExpClassByVal( S_LPCSTRArray *s, int size )
+{
+ return TakeLPCSTRArraySeqStructByVal( *s, size );
+}
+
+
+
+extern "C" DLL_EXPORT BOOL TakeStructArrayExpClassByVal( S_StructArray *s, int size )
+{
+ return TakeStructArraySeqStructByVal( *s, size );
+}
+
+/*----------------------------------------------------------------------------
+return a struct including a C array
+----------------------------------------------------------------------------*/
+extern "C" DLL_EXPORT S_INTArray* S_INTArray_Ret()
+{
+ INIT_EXPECTED_STRUCT( S_INTArray, ARRAY_SIZE, INT );
+
+ return expected;
+}
+
+extern "C" DLL_EXPORT S_UINTArray* S_UINTArray_Ret()
+{
+ INIT_EXPECTED_STRUCT( S_UINTArray, ARRAY_SIZE, UINT );
+
+ return expected;
+}
+
+extern "C" DLL_EXPORT S_SHORTArray* S_SHORTArray_Ret()
+{
+ INIT_EXPECTED_STRUCT( S_SHORTArray, ARRAY_SIZE, SHORT );
+
+ return expected;
+}
+
+extern "C" DLL_EXPORT S_WORDArray* S_WORDArray_Ret()
+{
+ INIT_EXPECTED_STRUCT( S_WORDArray, ARRAY_SIZE, WORD );
+
+ return expected;
+}
+
+extern "C" DLL_EXPORT S_LONG64Array* S_LONG64Array_Ret()
+{
+ INIT_EXPECTED_STRUCT( S_LONG64Array, ARRAY_SIZE, LONG64 );
+
+ return expected;
+}
+
+extern "C" DLL_EXPORT S_ULONG64Array* S_ULONG64Array_Ret()
+{
+ INIT_EXPECTED_STRUCT( S_ULONG64Array, ARRAY_SIZE, ULONG64 );
+
+ return expected;
+}
+
+extern "C" DLL_EXPORT S_DOUBLEArray* S_DOUBLEArray_Ret()
+{
+ INIT_EXPECTED_STRUCT( S_DOUBLEArray, ARRAY_SIZE, DOUBLE );
+
+ return expected;
+}
+
+extern "C" DLL_EXPORT S_FLOATArray* S_FLOATArray_Ret()
+{
+ INIT_EXPECTED_STRUCT( S_FLOATArray, ARRAY_SIZE, FLOAT );
+
+ return expected;
+}
+
+extern "C" DLL_EXPORT S_BYTEArray* S_BYTEArray_Ret()
+{
+ INIT_EXPECTED_STRUCT( S_BYTEArray, ARRAY_SIZE, BYTE );
+
+ return expected;
+}
+
+extern "C" DLL_EXPORT S_CHARArray* S_CHARArray_Ret()
+{
+ INIT_EXPECTED_STRUCT( S_CHARArray, ARRAY_SIZE, CHAR );
+
+ return expected;
+}
+
+extern "C" DLL_EXPORT S_LPSTRArray* S_LPSTRArray_Ret()
+{
+ S_LPSTRArray *expected = (S_LPSTRArray *)::CoTaskMemAlloc( sizeof(S_LPSTRArray) );
+ for ( size_t i = 0; i < ARRAY_SIZE; ++i )
+ expected->arr[i] = ToString(i);
+
+ return expected;
+}
+
+
+extern "C" DLL_EXPORT S_StructArray* S_StructArray_Ret()
+{
+ S_StructArray *expected = (S_StructArray *)::CoTaskMemAlloc( sizeof(S_StructArray) );
+ for ( size_t i = 0; i < ARRAY_SIZE; ++i )
+ {
+ expected->arr[i].x = i;
+ expected->arr[i].d = i;
+ expected->arr[i].l = i;
+ expected->arr[i].str = ToString(i);
+ }
+
+ return expected;
+} \ No newline at end of file
diff --git a/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValTest.cs b/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValTest.cs
new file mode 100644
index 0000000000..aaa30f502e
--- /dev/null
+++ b/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValTest.cs
@@ -0,0 +1,1072 @@
+using System;
+using System.Runtime.InteropServices;
+
+class TestHelper
+{
+ public static void Assert(bool exp,string msg="")
+ {
+ CoreFXTestLibrary.Assert.IsTrue(exp, msg);
+ }
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct S_INTArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public int[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct S_UINTArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public uint[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct S_SHORTArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public short[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct S_WORDArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public ushort[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct S_LONG64Array_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public long[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct S_ULONG64Array_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public ulong[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct S_DOUBLEArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public double[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct S_FLOATArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public float[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct S_BYTEArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public byte[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct S_CHARArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public char[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct S_INTPTRArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public IntPtr[] arr;
+}
+
+//struct array in a struct
+[StructLayout(LayoutKind.Sequential)]
+public struct TestStruct
+{
+ public int x;
+ public double d;
+ public long l;
+ public string str;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct S_StructArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public TestStruct[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct S_BOOLArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public bool[] arr;
+}
+
+
+[StructLayout(LayoutKind.Sequential)]
+public class C_INTArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public int[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public class C_UINTArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public uint[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public class C_SHORTArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public short[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public class C_WORDArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public ushort[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public class C_LONG64Array_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public long[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public class C_ULONG64Array_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public ulong[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public class C_DOUBLEArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public double[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public class C_FLOATArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public float[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public class C_BYTEArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public byte[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public class C_CHARArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public char[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public class C_LPSTRArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public string[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public class C_LPCSTRArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public string[] arr;
+}
+
+
+
+//struct array in a class
+[StructLayout(LayoutKind.Sequential)]
+public class C_StructArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public TestStruct[] arr;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public class C_BOOLArray_Seq
+{
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public bool[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public struct S_INTArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public int[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public struct S_UINTArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public uint[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public struct S_SHORTArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public short[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public struct S_WORDArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public ushort[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public struct S_LONG64Array_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE, ArraySubType = UnmanagedType.I8)]
+ public long[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public struct S_ULONG64Array_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public ulong[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public struct S_DOUBLEArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public double[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public struct S_FLOATArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public float[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public struct S_BYTEArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public byte[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public struct S_CHARArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public char[] arr;
+}
+
+
+[StructLayout(LayoutKind.Explicit)]
+public struct S_LPSTRArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public string[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public struct S_LPCSTRArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public string[] arr;
+}
+
+
+
+//struct array in a struct
+[StructLayout(LayoutKind.Explicit)]
+public struct S_StructArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public TestStruct[] arr;
+}
+
+
+[StructLayout(LayoutKind.Explicit)]
+public struct S_BOOLArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public bool[] arr;
+}
+
+
+[StructLayout(LayoutKind.Explicit)]
+public class C_INTArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public int[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public class C_UINTArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public uint[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public class C_SHORTArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public short[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public class C_WORDArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public ushort[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit, Pack = 8)]
+public class C_LONG64Array_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public long[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public class C_ULONG64Array_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public ulong[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public class C_DOUBLEArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public double[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public class C_FLOATArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public float[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public class C_BYTEArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public byte[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public class C_CHARArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public char[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public class C_LPSTRArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public string[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public class C_LPCSTRArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public string[] arr;
+}
+
+
+
+//struct array in a class
+[StructLayout(LayoutKind.Explicit)]
+public class C_StructArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public TestStruct[] arr;
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public class C_BOOLArray_Exp
+{
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Test.ARRAY_SIZE)]
+ public bool[] arr;
+}
+
+class Test
+{
+ //for RunTest1
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeIntArraySeqStructByVal([In]S_INTArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeUIntArraySeqStructByVal([In]S_UINTArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeShortArraySeqStructByVal([In]S_SHORTArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeWordArraySeqStructByVal([In]S_WORDArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeLong64ArraySeqStructByVal([In]S_LONG64Array_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeULong64ArraySeqStructByVal([In]S_ULONG64Array_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeDoubleArraySeqStructByVal([In]S_DOUBLEArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeFloatArraySeqStructByVal([In]S_FLOATArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeByteArraySeqStructByVal([In]S_BYTEArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeCharArraySeqStructByVal([In]S_CHARArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeIntPtrArraySeqStructByVal([In]S_INTPTRArray_Seq s, int size);
+
+
+
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeStructArraySeqStructByVal([In]S_StructArray_Seq s, int size);
+
+
+
+ //for RunTest2
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeIntArraySeqClassByVal([In]C_INTArray_Seq c, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeUIntArraySeqClassByVal([In]C_UINTArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeShortArraySeqClassByVal([In]C_SHORTArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeWordArraySeqClassByVal([In]C_WORDArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeLong64ArraySeqClassByVal([In]C_LONG64Array_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeULong64ArraySeqClassByVal([In]C_ULONG64Array_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeDoubleArraySeqClassByVal([In]C_DOUBLEArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeFloatArraySeqClassByVal([In]C_FLOATArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeByteArraySeqClassByVal([In]C_BYTEArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeCharArraySeqClassByVal([In]C_CHARArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeLPSTRArraySeqClassByVal([In]C_LPSTRArray_Seq s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeLPCSTRArraySeqClassByVal([In]C_LPCSTRArray_Seq s, int size);
+
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeStructArraySeqClassByVal([In]C_StructArray_Seq s, int size);
+
+
+ //for RunTest3
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeIntArrayExpStructByVal([In]S_INTArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeUIntArrayExpStructByVal([In]S_UINTArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeShortArrayExpStructByVal([In]S_SHORTArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeWordArrayExpStructByVal([In]S_WORDArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeLong64ArrayExpStructByVal([In]S_LONG64Array_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeULong64ArrayExpStructByVal([In]S_ULONG64Array_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeDoubleArrayExpStructByVal([In]S_DOUBLEArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeFloatArrayExpStructByVal([In]S_FLOATArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeByteArrayExpStructByVal([In]S_BYTEArray_Exp s, int size);
+
+
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeCharArrayExpStructByVal([In]S_CHARArray_Exp s, int size);
+
+
+
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeLPSTRArrayExpStructByVal([In]S_LPSTRArray_Exp s, int size);
+
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeLPCSTRArrayExpStructByVal([In]S_LPCSTRArray_Exp s, int size);
+
+
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeStructArrayExpStructByVal([In]S_StructArray_Exp s, int size);
+
+
+
+ //for RunTest4
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeIntArrayExpClassByVal([In]C_INTArray_Exp c, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeUIntArrayExpClassByVal([In]C_UINTArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeShortArrayExpClassByVal([In]C_SHORTArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeWordArrayExpClassByVal([In]C_WORDArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeLong64ArrayExpClassByVal([In]C_LONG64Array_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeULong64ArrayExpClassByVal([In]C_ULONG64Array_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeDoubleArrayExpClassByVal([In]C_DOUBLEArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeFloatArrayExpClassByVal([In]C_FLOATArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeByteArrayExpClassByVal([In]C_BYTEArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeCharArrayExpClassByVal([In]C_CHARArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeLPSTRArrayExpClassByVal([In]C_LPSTRArray_Exp s, int size);
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeLPCSTRArrayExpClassByVal([In]C_LPCSTRArray_Exp s, int size);
+
+ [DllImport("MarshalArrayByValNative")]
+ static extern bool TakeStructArrayExpClassByVal([In]C_StructArray_Exp s, int size);
+
+ //for RunTest5
+ //get struct on C++ side as sequential class
+ [DllImport("MarshalArrayByValNative")]
+ static extern C_INTArray_Seq S_INTArray_Ret();
+ [DllImport("MarshalArrayByValNative")]
+ static extern C_UINTArray_Seq S_UINTArray_Ret();
+ [DllImport("MarshalArrayByValNative")]
+ static extern C_SHORTArray_Seq S_SHORTArray_Ret();
+ [DllImport("MarshalArrayByValNative")]
+ static extern C_WORDArray_Seq S_WORDArray_Ret();
+ [DllImport("MarshalArrayByValNative")]
+ static extern C_LONG64Array_Seq S_LONG64Array_Ret();
+ [DllImport("MarshalArrayByValNative")]
+ static extern C_ULONG64Array_Seq S_ULONG64Array_Ret();
+ [DllImport("MarshalArrayByValNative")]
+ static extern C_DOUBLEArray_Seq S_DOUBLEArray_Ret();
+ [DllImport("MarshalArrayByValNative")]
+ static extern C_FLOATArray_Seq S_FLOATArray_Ret();
+ [DllImport("MarshalArrayByValNative")]
+ static extern C_BYTEArray_Seq S_BYTEArray_Ret();
+ [DllImport("MarshalArrayByValNative")]
+ static extern C_CHARArray_Seq S_CHARArray_Ret();
+ [DllImport("MarshalArrayByValNative")]
+ static extern C_LPSTRArray_Seq S_LPSTRArray_Ret();
+
+ [DllImport("MarshalArrayByValNative")]
+ static extern C_StructArray_Seq S_StructArray_Ret();
+
+ //for RunTest6
+ //get struct on C++ side as explicit class
+ [DllImport("MarshalArrayByValNative", EntryPoint = "S_INTArray_Ret")]
+ static extern C_INTArray_Exp S_INTArray_Ret2();
+ [DllImport("MarshalArrayByValNative", EntryPoint = "S_UINTArray_Ret")]
+ static extern C_UINTArray_Exp S_UINTArray_Ret2();
+ [DllImport("MarshalArrayByValNative", EntryPoint = "S_SHORTArray_Ret")]
+ static extern C_SHORTArray_Exp S_SHORTArray_Ret2();
+ [DllImport("MarshalArrayByValNative", EntryPoint = "S_WORDArray_Ret")]
+ static extern C_WORDArray_Exp S_WORDArray_Ret2();
+ [DllImport("MarshalArrayByValNative", EntryPoint = "S_LONG64Array_Ret")]
+ static extern C_LONG64Array_Exp S_LONG64Array_Ret2();
+ [DllImport("MarshalArrayByValNative", EntryPoint = "S_ULONG64Array_Ret")]
+ static extern C_ULONG64Array_Exp S_ULONG64Array_Ret2();
+ [DllImport("MarshalArrayByValNative", EntryPoint = "S_DOUBLEArray_Ret")]
+ static extern C_DOUBLEArray_Exp S_DOUBLEArray_Ret2();
+ [DllImport("MarshalArrayByValNative", EntryPoint = "S_FLOATArray_Ret")]
+ static extern C_FLOATArray_Exp S_FLOATArray_Ret2();
+ [DllImport("MarshalArrayByValNative", EntryPoint = "S_BYTEArray_Ret")]
+ static extern C_BYTEArray_Exp S_BYTEArray_Ret2();
+ [DllImport("MarshalArrayByValNative", EntryPoint = "S_CHARArray_Ret")]
+ static extern C_CHARArray_Exp S_CHARArray_Ret2();
+ [DllImport("MarshalArrayByValNative", EntryPoint = "S_LPSTRArray_Ret")]
+ static extern C_LPSTRArray_Exp S_LPSTRArray_Ret2();
+
+ [DllImport("MarshalArrayByValNative", EntryPoint = "S_StructArray_Ret")]
+ static extern C_StructArray_Exp S_StructArray_Ret2();
+
+ internal const int ARRAY_SIZE = 100;
+
+ static T[] InitArray<T>(int size)
+ {
+ T[] array = new T[size];
+
+ for (int i = 0; i < array.Length; i++)
+ array[i] = (T)Convert.ChangeType(i, typeof(T));
+
+ return array;
+ }
+
+ static TestStruct[] InitStructArray(int size)
+ {
+ TestStruct[] array = new TestStruct[size];
+
+ for (int i = 0; i < array.Length; i++)
+ {
+ array[i].x = i;
+ array[i].d = i;
+ array[i].l = i;
+ array[i].str = i.ToString();
+ }
+
+ return array;
+ }
+
+ static bool[] InitBoolArray(int size)
+ {
+ bool[] array = new bool[size];
+
+ for (int i = 0; i < array.Length; i++)
+ {
+ if (i % 2 == 0)
+ array[i] = true;
+ else
+ array[i] = false;
+ }
+
+ return array;
+ }
+
+ static IntPtr[] InitIntPtrArray(int size)
+ {
+ IntPtr[] array = new IntPtr[size];
+
+ for (int i = 0; i < array.Length; i++)
+ array[i] = new IntPtr(i);
+
+ return array;
+ }
+
+ static bool Equals<T>(T[] arr1, T[] arr2)
+ {
+ if (arr1 == null && arr2 == null)
+ return true;
+ else if (arr1 == null && arr2 != null)
+ return false;
+ else if (arr1 != null && arr2 == null)
+ return false;
+ else if (arr1.Length != arr2.Length)
+ return false;
+
+ for (int i = 0; i < arr2.Length; ++i)
+ {
+ if (!Object.Equals(arr1[i], arr2[i]))
+ {
+ Console.WriteLine("Array marshaling error, when type is {0}", typeof(T));
+ Console.WriteLine("Expected: {0}, Actual: {1}", arr1[i], arr2[i]);
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ static bool TestStructEquals(TestStruct[] tsArr1, TestStruct[] tsArr2)
+ {
+ if (tsArr1 == null && tsArr2 == null)
+ return true;
+ else if (tsArr1 == null && tsArr2 != null)
+ return false;
+ else if (tsArr1 != null && tsArr2 == null)
+ return false;
+ else if (tsArr1.Length != tsArr2.Length)
+ return false;
+
+ bool result = true;
+ for (int i = 0; i < tsArr2.Length; i++)
+ {
+ result = (tsArr1[i].x == tsArr2[i].x &&
+ tsArr1[i].d == tsArr2[i].d &&
+ tsArr1[i].l == tsArr2[i].l &&
+ tsArr1[i].str == tsArr2[i].str) && result;
+ }
+
+ return result;
+ }
+
+
+
+ static bool RunTest1(string report)
+ {
+ Console.WriteLine(report);
+
+ S_INTArray_Seq s1 = new S_INTArray_Seq();
+ s1.arr = InitArray<int>(ARRAY_SIZE);
+ TestHelper.Assert(TakeIntArraySeqStructByVal(s1, s1.arr.Length), "TakeIntArraySeqStructByVal");
+
+ S_UINTArray_Seq s2 = new S_UINTArray_Seq();
+ s2.arr = InitArray<uint>(ARRAY_SIZE);
+ TestHelper.Assert(TakeUIntArraySeqStructByVal(s2, s2.arr.Length), "TakeUIntArraySeqStructByVal");
+
+ S_SHORTArray_Seq s3 = new S_SHORTArray_Seq();
+ s3.arr = InitArray<short>(ARRAY_SIZE);
+ TestHelper.Assert(TakeShortArraySeqStructByVal(s3, s3.arr.Length), "TakeShortArraySeqStructByVal");
+
+ S_WORDArray_Seq s4 = new S_WORDArray_Seq();
+ s4.arr = InitArray<ushort>(ARRAY_SIZE);
+ TestHelper.Assert(TakeWordArraySeqStructByVal(s4, s4.arr.Length), "TakeWordArraySeqStructByVal");
+
+ S_LONG64Array_Seq s5 = new S_LONG64Array_Seq();
+ s5.arr = InitArray<long>(ARRAY_SIZE);
+ TestHelper.Assert(TakeLong64ArraySeqStructByVal(s5, s5.arr.Length), "TakeLong64ArraySeqStructByVal");
+
+ S_ULONG64Array_Seq s6 = new S_ULONG64Array_Seq();
+ s6.arr = InitArray<ulong>(ARRAY_SIZE);
+ TestHelper.Assert(TakeULong64ArraySeqStructByVal(s6, s6.arr.Length), "TakeULong64ArraySeqStructByVal");
+
+ S_DOUBLEArray_Seq s7 = new S_DOUBLEArray_Seq();
+ s7.arr = InitArray<double>(ARRAY_SIZE);
+ TestHelper.Assert(TakeDoubleArraySeqStructByVal(s7, s7.arr.Length), "TakeDoubleArraySeqStructByVal");
+
+ S_FLOATArray_Seq s8 = new S_FLOATArray_Seq();
+ s8.arr = InitArray<float>(ARRAY_SIZE);
+ TestHelper.Assert(TakeFloatArraySeqStructByVal(s8, s8.arr.Length), "TakeFloatArraySeqStructByVal");
+
+ S_BYTEArray_Seq s9 = new S_BYTEArray_Seq();
+ s9.arr = InitArray<byte>(ARRAY_SIZE);
+ TestHelper.Assert(TakeByteArraySeqStructByVal(s9, s9.arr.Length), "TakeByteArraySeqStructByVal");
+
+ S_CHARArray_Seq s10 = new S_CHARArray_Seq();
+ s10.arr = InitArray<char>(ARRAY_SIZE);
+ TestHelper.Assert(TakeCharArraySeqStructByVal(s10, s10.arr.Length), "TakeCharArraySeqStructByVal");
+
+ S_INTPTRArray_Seq s11 = new S_INTPTRArray_Seq();
+ s11.arr = InitIntPtrArray(ARRAY_SIZE);
+ TestHelper.Assert(TakeIntPtrArraySeqStructByVal(s11, s11.arr.Length), "TakeIntPtrArraySeqStructByVal");
+
+
+ S_StructArray_Seq s14 = new S_StructArray_Seq();
+ s14.arr = InitStructArray(ARRAY_SIZE);
+ TestHelper.Assert(TakeStructArraySeqStructByVal(s14, s14.arr.Length),"TakeStructArraySeqStructByVal");
+
+ return true;
+ }
+
+ static bool RunTest2(string report)
+ {
+
+ C_INTArray_Seq c1 = new C_INTArray_Seq();
+ c1.arr = InitArray<int>(ARRAY_SIZE);
+ TestHelper.Assert(TakeIntArraySeqClassByVal(c1, c1.arr.Length));
+
+ C_UINTArray_Seq c2 = new C_UINTArray_Seq();
+ c2.arr = InitArray<uint>(ARRAY_SIZE);
+ TestHelper.Assert(TakeUIntArraySeqClassByVal(c2, c2.arr.Length));
+
+ C_SHORTArray_Seq c3 = new C_SHORTArray_Seq();
+ c3.arr = InitArray<short>(ARRAY_SIZE);
+ TestHelper.Assert(TakeShortArraySeqClassByVal(c3, c3.arr.Length));
+
+ C_WORDArray_Seq c4 = new C_WORDArray_Seq();
+ c4.arr = InitArray<ushort>(ARRAY_SIZE);
+ TestHelper.Assert(TakeWordArraySeqClassByVal(c4, c4.arr.Length));
+
+ C_LONG64Array_Seq c5 = new C_LONG64Array_Seq();
+ c5.arr = InitArray<long>(ARRAY_SIZE);
+ TestHelper.Assert(TakeLong64ArraySeqClassByVal(c5, c5.arr.Length));
+
+ C_ULONG64Array_Seq c6 = new C_ULONG64Array_Seq();
+ c6.arr = InitArray<ulong>(ARRAY_SIZE);
+ TestHelper.Assert(TakeULong64ArraySeqClassByVal(c6, c6.arr.Length));
+
+ C_DOUBLEArray_Seq c7 = new C_DOUBLEArray_Seq();
+ c7.arr = InitArray<double>(ARRAY_SIZE);
+ TestHelper.Assert(TakeDoubleArraySeqClassByVal(c7, c7.arr.Length));
+
+ C_FLOATArray_Seq c8 = new C_FLOATArray_Seq();
+ c8.arr = InitArray<float>(ARRAY_SIZE);
+ TestHelper.Assert(TakeFloatArraySeqClassByVal(c8, c8.arr.Length));
+
+ C_BYTEArray_Seq c9 = new C_BYTEArray_Seq();
+ c9.arr = InitArray<byte>(ARRAY_SIZE);
+ TestHelper.Assert(TakeByteArraySeqClassByVal(c9, c9.arr.Length));
+
+ C_CHARArray_Seq c10 = new C_CHARArray_Seq();
+ c10.arr = InitArray<char>(ARRAY_SIZE);
+ TestHelper.Assert(TakeCharArraySeqClassByVal(c10, c10.arr.Length));
+
+ C_LPSTRArray_Seq c11 = new C_LPSTRArray_Seq();
+ c11.arr = InitArray<string>(ARRAY_SIZE);
+ TestHelper.Assert(TakeLPSTRArraySeqClassByVal(c11, c11.arr.Length));
+
+ C_LPCSTRArray_Seq c12 = new C_LPCSTRArray_Seq();
+ c12.arr = InitArray<string>(ARRAY_SIZE);
+ TestHelper.Assert(TakeLPCSTRArraySeqClassByVal(c12, c12.arr.Length));
+
+
+ C_StructArray_Seq c14 = new C_StructArray_Seq();
+ c14.arr = InitStructArray(ARRAY_SIZE);
+ TestHelper.Assert(TakeStructArraySeqClassByVal(c14, c14.arr.Length));
+
+ return true;
+ }
+
+
+ static bool RunTest3(string report)
+ {
+ Console.WriteLine(report);
+
+ S_INTArray_Exp s1 = new S_INTArray_Exp();
+ s1.arr = InitArray<int>(ARRAY_SIZE);
+ TestHelper.Assert(TakeIntArrayExpStructByVal(s1, s1.arr.Length), "TakeIntArrayExpStructByVal");
+
+ S_UINTArray_Exp s2 = new S_UINTArray_Exp();
+ s2.arr = InitArray<uint>(ARRAY_SIZE);
+ TestHelper.Assert(TakeUIntArrayExpStructByVal(s2, s2.arr.Length), "TakeUIntArrayExpStructByVal");
+
+ S_SHORTArray_Exp s3 = new S_SHORTArray_Exp();
+ s3.arr = InitArray<short>(ARRAY_SIZE);
+ TestHelper.Assert(TakeShortArrayExpStructByVal(s3, s3.arr.Length), "TakeShortArrayExpStructByVal");
+
+ S_WORDArray_Exp s4 = new S_WORDArray_Exp();
+ s4.arr = InitArray<ushort>(ARRAY_SIZE);
+ TestHelper.Assert(TakeWordArrayExpStructByVal(s4, s4.arr.Length), "TakeWordArrayExpStructByVal");
+
+ S_LONG64Array_Exp s5 = new S_LONG64Array_Exp();
+ s5.arr = InitArray<long>(ARRAY_SIZE);
+ TestHelper.Assert(TakeLong64ArrayExpStructByVal(s5, s5.arr.Length), "TakeLong64ArrayExpStructByVal");
+
+ S_ULONG64Array_Exp s6 = new S_ULONG64Array_Exp();
+ s6.arr = InitArray<ulong>(ARRAY_SIZE);
+ TestHelper.Assert(TakeULong64ArrayExpStructByVal(s6, s6.arr.Length), "TakeULong64ArrayExpStructByVal");
+
+ S_DOUBLEArray_Exp s7 = new S_DOUBLEArray_Exp();
+ s7.arr = InitArray<double>(ARRAY_SIZE);
+ TestHelper.Assert(TakeDoubleArrayExpStructByVal(s7, s7.arr.Length), "TakeDoubleArrayExpStructByVal");
+
+ S_FLOATArray_Exp s8 = new S_FLOATArray_Exp();
+ s8.arr = InitArray<float>(ARRAY_SIZE);
+ TestHelper.Assert(TakeFloatArrayExpStructByVal(s8, s8.arr.Length), "TakeFloatArrayExpStructByVal");
+
+ S_BYTEArray_Exp s9 = new S_BYTEArray_Exp();
+ s9.arr = InitArray<byte>(ARRAY_SIZE);
+ TestHelper.Assert(TakeByteArrayExpStructByVal(s9, s9.arr.Length), "TakeByteArrayExpStructByVal");
+
+ S_CHARArray_Exp s10 = new S_CHARArray_Exp();
+ s10.arr = InitArray<char>(ARRAY_SIZE);
+ TestHelper.Assert(TakeCharArrayExpStructByVal(s10, s10.arr.Length), "TakeCharArrayExpStructByVal");
+
+ S_LPSTRArray_Exp s11 = new S_LPSTRArray_Exp();
+ s11.arr = InitArray<string>(ARRAY_SIZE);
+ TestHelper.Assert(TakeLPSTRArrayExpStructByVal(s11, s11.arr.Length));
+
+ S_LPCSTRArray_Exp s12 = new S_LPCSTRArray_Exp();
+ s12.arr = InitArray<string>(ARRAY_SIZE);
+ TestHelper.Assert(TakeLPCSTRArrayExpStructByVal(s12, s12.arr.Length));
+
+
+ S_StructArray_Exp s14 = new S_StructArray_Exp();
+ s14.arr = InitStructArray(ARRAY_SIZE);
+ TestHelper.Assert(TakeStructArrayExpStructByVal(s14, s14.arr.Length));
+
+ return true;
+ }
+
+
+ static bool RunTest4(string report)
+ {
+ Console.WriteLine(report);
+
+ C_INTArray_Exp c1 = new C_INTArray_Exp();
+ c1.arr = InitArray<int>(ARRAY_SIZE);
+ TestHelper.Assert(TakeIntArrayExpClassByVal(c1, c1.arr.Length));
+
+ C_UINTArray_Exp c2 = new C_UINTArray_Exp();
+ c2.arr = InitArray<uint>(ARRAY_SIZE);
+ TestHelper.Assert(TakeUIntArrayExpClassByVal(c2, c2.arr.Length));
+
+ C_SHORTArray_Exp c3 = new C_SHORTArray_Exp();
+ c3.arr = InitArray<short>(ARRAY_SIZE);
+ TestHelper.Assert(TakeShortArrayExpClassByVal(c3, c3.arr.Length));
+
+ C_WORDArray_Exp c4 = new C_WORDArray_Exp();
+ c4.arr = InitArray<ushort>(ARRAY_SIZE);
+ TestHelper.Assert(TakeWordArrayExpClassByVal(c4, c4.arr.Length));
+
+ C_LONG64Array_Exp c5 = new C_LONG64Array_Exp();
+ c5.arr = InitArray<long>(ARRAY_SIZE);
+ TestHelper.Assert(TakeLong64ArrayExpClassByVal(c5, c5.arr.Length));
+
+ C_ULONG64Array_Exp c6 = new C_ULONG64Array_Exp();
+ c6.arr = InitArray<ulong>(ARRAY_SIZE);
+ TestHelper.Assert(TakeULong64ArrayExpClassByVal(c6, c6.arr.Length));
+
+ C_DOUBLEArray_Exp c7 = new C_DOUBLEArray_Exp();
+ c7.arr = InitArray<double>(ARRAY_SIZE);
+ TestHelper.Assert(TakeDoubleArrayExpClassByVal(c7, c7.arr.Length));
+
+ C_FLOATArray_Exp c8 = new C_FLOATArray_Exp();
+ c8.arr = InitArray<float>(ARRAY_SIZE);
+ TestHelper.Assert(TakeFloatArrayExpClassByVal(c8, c8.arr.Length));
+
+ C_BYTEArray_Exp c9 = new C_BYTEArray_Exp();
+ c9.arr = InitArray<byte>(ARRAY_SIZE);
+ TestHelper.Assert(TakeByteArrayExpClassByVal(c9, c9.arr.Length));
+
+ C_CHARArray_Exp c10 = new C_CHARArray_Exp();
+ c10.arr = InitArray<char>(ARRAY_SIZE);
+ TestHelper.Assert(TakeCharArrayExpClassByVal(c10, c10.arr.Length));
+
+ C_LPSTRArray_Exp c11 = new C_LPSTRArray_Exp();
+ c11.arr = InitArray<string>(ARRAY_SIZE);
+ TestHelper.Assert(TakeLPSTRArrayExpClassByVal(c11, c11.arr.Length));
+
+ C_LPCSTRArray_Exp c12 = new C_LPCSTRArray_Exp();
+ c12.arr = InitArray<string>(ARRAY_SIZE);
+ TestHelper.Assert(TakeLPCSTRArrayExpClassByVal(c12, c12.arr.Length));
+
+
+
+ C_StructArray_Exp c14 = new C_StructArray_Exp();
+ c14.arr = InitStructArray(ARRAY_SIZE);
+ TestHelper.Assert(TakeStructArrayExpClassByVal(c14, c14.arr.Length));
+
+ return true;
+ }
+
+ static bool RunTest5(string report)
+ {
+
+ C_INTArray_Seq retval1 = S_INTArray_Ret();
+ TestHelper.Assert(Equals(InitArray<int>(ARRAY_SIZE), retval1.arr));
+
+ C_UINTArray_Seq retval2 = S_UINTArray_Ret();
+ TestHelper.Assert(Equals(InitArray<uint>(ARRAY_SIZE), retval2.arr));
+
+ C_SHORTArray_Seq retval3 = S_SHORTArray_Ret();
+ TestHelper.Assert(Equals(InitArray<short>(ARRAY_SIZE), retval3.arr));
+
+ C_WORDArray_Seq retval4 = S_WORDArray_Ret();
+ TestHelper.Assert(Equals(InitArray<ushort>(ARRAY_SIZE), retval4.arr));
+
+ C_LONG64Array_Seq retval5 = S_LONG64Array_Ret();
+ TestHelper.Assert(Equals(InitArray<long>(ARRAY_SIZE), retval5.arr));
+
+ C_ULONG64Array_Seq retval6 = S_ULONG64Array_Ret();
+ TestHelper.Assert(Equals(InitArray<ulong>(ARRAY_SIZE), retval6.arr));
+
+ C_DOUBLEArray_Seq retval7 = S_DOUBLEArray_Ret();
+ TestHelper.Assert(Equals(InitArray<double>(ARRAY_SIZE), retval7.arr));
+
+ C_FLOATArray_Seq retval8 = S_FLOATArray_Ret();
+ TestHelper.Assert(Equals(InitArray<float>(ARRAY_SIZE), retval8.arr));
+
+ C_BYTEArray_Seq retval9 = S_BYTEArray_Ret();
+ TestHelper.Assert(Equals(InitArray<byte>(ARRAY_SIZE), retval9.arr));
+
+ C_CHARArray_Seq retval10 = S_CHARArray_Ret();
+ TestHelper.Assert(Equals(InitArray<char>(ARRAY_SIZE), retval10.arr));
+
+ C_LPSTRArray_Seq retval11 = S_LPSTRArray_Ret();
+ TestHelper.Assert(Equals(InitArray<string>(ARRAY_SIZE), retval11.arr));
+
+
+
+ C_StructArray_Seq retval13 = S_StructArray_Ret();
+ TestHelper.Assert(TestStructEquals(InitStructArray(ARRAY_SIZE), retval13.arr));
+
+ return true;
+ }
+
+ static bool RunTest6(string report)
+ {
+
+ C_INTArray_Exp retval1 = S_INTArray_Ret2();
+ TestHelper.Assert(Equals(InitArray<int>(ARRAY_SIZE), retval1.arr));
+
+ C_UINTArray_Exp retval2 = S_UINTArray_Ret2();
+ TestHelper.Assert(Equals(InitArray<uint>(ARRAY_SIZE), retval2.arr));
+
+ C_SHORTArray_Exp retval3 = S_SHORTArray_Ret2();
+ TestHelper.Assert(Equals(InitArray<short>(ARRAY_SIZE), retval3.arr));
+
+ C_WORDArray_Exp retval4 = S_WORDArray_Ret2();
+ TestHelper.Assert(Equals(InitArray<ushort>(ARRAY_SIZE), retval4.arr));
+
+ C_LONG64Array_Exp retval5 = S_LONG64Array_Ret2();
+ TestHelper.Assert(Equals(InitArray<long>(ARRAY_SIZE), retval5.arr));
+
+ C_ULONG64Array_Exp retval6 = S_ULONG64Array_Ret2();
+ TestHelper.Assert(Equals(InitArray<ulong>(ARRAY_SIZE), retval6.arr));
+
+ C_DOUBLEArray_Exp retval7 = S_DOUBLEArray_Ret2();
+ TestHelper.Assert(Equals(InitArray<double>(ARRAY_SIZE), retval7.arr));
+
+ C_FLOATArray_Exp retval8 = S_FLOATArray_Ret2();
+ TestHelper.Assert(Equals(InitArray<float>(ARRAY_SIZE), retval8.arr));
+
+ C_BYTEArray_Exp retval9 = S_BYTEArray_Ret2();
+ TestHelper.Assert(Equals(InitArray<byte>(ARRAY_SIZE), retval9.arr));
+
+ C_CHARArray_Exp retval10 = S_CHARArray_Ret2();
+ TestHelper.Assert(Equals(InitArray<char>(ARRAY_SIZE), retval10.arr));
+
+ C_LPSTRArray_Exp retval11 = S_LPSTRArray_Ret2();
+ TestHelper.Assert(Equals(InitArray<string>(ARRAY_SIZE), retval11.arr));
+
+
+
+ C_StructArray_Exp retval13 = S_StructArray_Ret2();
+ TestHelper.Assert(TestStructEquals(InitStructArray(ARRAY_SIZE), retval13.arr));
+
+ return true;
+ }
+
+ static int Main(string[] args)
+ {
+ RunTest1("RunTest1 : Marshal array as field as ByValArray in sequential struct as parameter.");
+ RunTest3("RunTest3 : Marshal array as field as ByValArray in explicit struct as parameter.");
+
+ RunTest2("RunTest2 : Marshal array as field as ByValArray in sequential class as parameter.");
+ RunTest4("RunTest4 : Marshal array as field as ByValArray in explicit class as parameter.");
+ RunTest5("RunTest5 : Marshal array as field as ByValArray in sequential class as return type.");
+ RunTest6("RunTest6 : Marshal array as field as ByValArray in explicit class as return type.");
+ return 100;
+ }
+}
diff --git a/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValTest.csproj b/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValTest.csproj
new file mode 100644
index 0000000000..ac78c7ba0b
--- /dev/null
+++ b/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValTest.csproj
@@ -0,0 +1,48 @@
+<?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>MarshalArrayByValTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <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="MarshalArrayByValTest.cs" />
+ <Compile Include="..\..\common\Assertion.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj">
+ <Project>{c8c0dc74-fac4-45b1-81fe-70c4808366e0}</Project>
+ <Name>CoreCLRTestLibrary</Name>
+ </ProjectReference>
+ <ProjectReference Include="CMakeLists.txt" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Interop/ArrayMarshalling/ByValArray/project.json b/tests/src/Interop/ArrayMarshalling/ByValArray/project.json
new file mode 100644
index 0000000000..cd536cf30e
--- /dev/null
+++ b/tests/src/Interop/ArrayMarshalling/ByValArray/project.json
@@ -0,0 +1,33 @@
+{
+ "dependencies": {
+ "System.Diagnostics.Process": "4.0.0-beta-23302",
+ "System.IO": "4.0.10-beta-23302",
+ "System.IO.FileSystem": "4.0.0-beta-23302",
+ "System.IO.FileSystem.Primitives": "4.0.0-beta-23302",
+ "System.Runtime": "4.0.20-beta-23302",
+ "System.Runtime.Extensions": "4.0.10-beta-23302",
+ "System.Runtime.Handles": "4.0.0-beta-23302",
+ "System.Runtime.Loader": "4.0.0-beta-23302",
+ "System.Threading": "4.0.10-beta-23302",
+ "System.Globalization.Calendars": "4.0.0-beta-23302",
+ "System.Globalization": "4.0.10-beta-23302",
+ "System.Text.Encoding": "4.0.10-beta-23302",
+ "System.Runtime.InteropServices": "4.0.20-beta-23302",
+ "System.Collections": "4.0.10-beta-23302",
+ "System.Console": "4.0.0-beta-23302",
+ "System.Reflection": "4.0.10-beta-23302",
+ "System.Reflection.Primitives": "4.0.0-beta-23302",
+ "System.ComponentModel": "4.0.1-beta-23302",
+ "System.Xml.ReaderWriter": "4.0.11-beta-23302",
+ "System.Collections.NonGeneric": "4.0.1-beta-23302",
+ "System.Collections.Specialized": "4.0.1-beta-23302",
+ "System.Linq": "4.0.1-beta-23302",
+ "System.Linq.Queryable": "4.0.1-beta-23302",
+ "System.Xml.XmlSerializer": "4.0.11-beta-23302",
+ "System.Xml.XmlDocument": "4.0.1-beta-23302",
+ "System.Xml.XDocument": "4.0.11-beta-23302"
+ },
+ "frameworks": {
+ "dnxcore50": {}
+ }
+} \ No newline at end of file
diff --git a/tests/src/Interop/CMakeLists.txt b/tests/src/Interop/CMakeLists.txt
new file mode 100644
index 0000000000..b08ccc1bfe
--- /dev/null
+++ b/tests/src/Interop/CMakeLists.txt
@@ -0,0 +1,8 @@
+
+include_directories(common)
+
+add_subdirectory(PrimitiveMarshalling/Bool)
+add_subdirectory(PrimitiveMarshalling/UIntPtr)
+add_subdirectory(ArrayMarshalling/BoolArray)
+add_subdirectory(ArrayMarshalling/ByValArray)
+add_subdirectory(ReversePInvoke/Marshalling) \ No newline at end of file
diff --git a/tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp b/tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp
new file mode 100644
index 0000000000..7af339e8d4
--- /dev/null
+++ b/tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp
@@ -0,0 +1,171 @@
+
+#include <xplatform.h>
+#include <stdio.h>
+
+
+BOOL boolManaged = true;
+BOOL boolNative = false;
+
+extern "C" DLL_EXPORT BOOL __stdcall Marshal_In(/*[in]*/BOOL boolValue)
+{
+ //Check the input
+ if(boolValue != boolManaged)
+ {
+ printf("Error in Function Marshal_In(Native Client)\n");
+
+ //Expected
+ printf("Expected: %s", (boolManaged)?"true":"false");
+
+ //Actual
+ printf("Actual: %s", (boolValue)?"true":"false");
+
+ //Return the error value instead if verification failed
+ return false;
+ }
+
+ return true;
+}
+
+extern "C" DLL_EXPORT BOOL __stdcall Marshal_InOut(/*[In,Out]*/BOOL boolValue)
+{
+ //Check the input
+ if(boolValue != boolManaged)
+ {
+ printf("Error in Function Marshal_InOut(Native Client)\n");
+
+ //Expected
+ printf("Expected: %s", (boolManaged)?"true":"false");
+
+ //Actual
+ printf("Actual: %s", (boolValue)?"true":"false");
+
+ //Return the error value instead if verification failed
+ return false;
+ }
+
+ //In-Place Change
+ boolValue = boolNative;
+
+ //Return
+ return true;
+}
+
+extern "C" DLL_EXPORT BOOL __stdcall Marshal_Out(/*[Out]*/BOOL boolValue)
+{
+ //In-Place Change
+ boolValue = boolNative;
+
+ //Return
+ return true;
+}
+
+extern "C" DLL_EXPORT BOOL __stdcall MarshalPointer_In(/*[in]*/BOOL *pboolValue)
+{
+ //Check the input
+ if(*pboolValue != boolManaged)
+ {
+ printf("Error in Function MarshalPointer_In(Native Client)\n");
+
+ //Expected
+ printf("Expected: %s", (boolManaged)?"true":"false");
+
+ //Actual
+ printf("Actual: %s", (*pboolValue)?"true":"false");
+
+ //Return the error value instead if verification failed
+ return false;
+ }
+
+ return true;
+}
+
+extern "C" DLL_EXPORT BOOL __stdcall MarshalPointer_InOut(/*[in,out]*/BOOL *pboolValue)
+{
+ //Check the input
+ if(*pboolValue != boolManaged)
+ {
+ printf("Error in Function MarshalPointer_InOut(Native Client)\n");
+
+ //Expected
+ printf("Expected: %s", (boolManaged)?"true":"false");
+
+ //Actual
+ printf("Actual: %s", (*pboolValue)?"true":"false");
+
+ //Return the error value instead if verification failed
+ return false;
+ }
+
+ //In-Place Change
+ *pboolValue = boolNative;
+
+ //Return
+ return true;
+}
+
+extern "C" DLL_EXPORT BOOL __stdcall MarshalPointer_Out(/*[out]*/ BOOL *pboolValue)
+{
+ //In-Place Change
+ *pboolValue = boolNative;
+
+ //Return
+ return true;
+}
+
+#pragma warning(push)
+// 'BOOL' forcing value to bool 'true' or 'false'
+#pragma warning(disable: 4800)
+
+extern "C" DLL_EXPORT bool __stdcall Marshal_As_In(/*[in]*/bool boolValue)
+{
+ //Check the input
+ if(boolValue != (bool)boolManaged)
+ {
+ printf("Error in Function Marshal_As_In(Native Client)\n");
+
+ //Expected
+ printf("Expected: %s", (boolManaged)?"true":"false");
+
+ //Actual
+ printf("Actual: %s", (boolValue)?"true":"false");
+
+ //Return the error value instead if verification failed
+ return false;
+ }
+
+ return true;
+}
+
+extern "C" DLL_EXPORT bool __stdcall Marshal_As_InOut(/*[In,Out]*/bool boolValue)
+{
+ //Check the input
+ if(boolValue != (bool)boolManaged)
+ {
+ printf("Error in Function Marshal_As_InOut(Native Client)\n");
+
+ //Expected
+ printf("Expected: %s", (boolManaged)?"true":"false");
+
+ //Actual
+ printf("Actual: %s", (boolValue)?"true":"false");
+
+ //Return the error value instead if verification failed
+ return false;
+ }
+
+ //In-Place Change
+ boolValue = (bool)boolNative;
+
+ //Return
+ return true;
+}
+
+extern "C" DLL_EXPORT bool __stdcall Marshal_As_Out(/*[Out]*/bool boolValue)
+{
+ //In-Place Change
+ boolValue = (bool)boolNative;
+
+ //Return
+ return true;
+}
+#pragma warning(pop)
diff --git a/tests/src/Interop/PrimitiveMarshalling/Bool/BoolTest.cs b/tests/src/Interop/PrimitiveMarshalling/Bool/BoolTest.cs
new file mode 100644
index 0000000000..c84c42b643
--- /dev/null
+++ b/tests/src/Interop/PrimitiveMarshalling/Bool/BoolTest.cs
@@ -0,0 +1,119 @@
+using System.Runtime.InteropServices;
+using System;
+using System.Reflection;
+using System.Text;
+
+class Test
+{
+ static void ReportFailure(string describe, bool expect, bool actual)
+ {
+ throw new Exception(" === Fail: " + describe + "\n\tExpected:" + expect + "\n\tActual:" + actual);
+ }
+
+ 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);
+ if (!boolValueRet1)
+ {
+ ReportFailure("Method Marshal_In[Managed Side],The return value is wrong", true, boolValueRet1);
+ }
+
+ //TestMethod2
+ bool boolValue2 = boolManaged;
+ bool boolValueRet2 = NativeMethods.Marshal_InOut(boolValue2);
+ if (!boolValueRet2)
+ {
+ ReportFailure("Method Marshal_InOut[Managed Side],The return value is wrong", true, boolValueRet2);
+ }
+ if (boolValue2 != boolManaged)
+ {
+ ReportFailure("Method Marshal_InOut[Managed Side],The parameter value is changed", boolManaged, boolValue2);
+ }
+
+ //TestMethod3
+ bool boolValue3 = boolManaged;
+ bool boolValueRet3 = NativeMethods.Marshal_Out(boolValue3);
+ if (!boolValueRet3)
+ {
+ ReportFailure("Method Marshal_Out[Managed Side],The return value is wrong", true, boolValueRet3);
+ }
+ if (boolValue3 != boolManaged)
+ {
+ ReportFailure("Method Marshal_Out[Managed Side],The parameter value is changed", boolManaged, boolValue3);
+ }
+
+ //TestMethod4
+ bool boolValue4 = boolManaged;
+ bool boolValueRet4 = NativeMethods.MarshalPointer_In(ref boolValue4);
+ if (!boolValueRet4)
+ {
+ ReportFailure("Method MarshalPointer_In[Managed Side],The return value is wrong", true, boolValueRet4);
+ }
+ if (boolValue4 != boolManaged)
+ {
+ ReportFailure("Method MarshalPointer_In[Managed Side],The parameter value is changed", boolManaged, boolValue4);
+ }
+
+ //TestMethod5
+ bool boolValue5 = boolManaged;
+ bool boolValueRet5 = NativeMethods.MarshalPointer_InOut(ref boolValue5);
+ if (!boolValueRet5)
+ {
+ ReportFailure("Method MarshalPointer_InOut[Managed Side],The return value is wrong", true, boolValueRet5);
+ }
+ if (boolValue5 != boolNative)
+ {
+ ReportFailure("Method MarshalPointer_InOut[Managed Side],The passed value is wrong", boolNative, boolValue5);
+ }
+
+ //TestMethod6
+ bool boolValue6 = boolManaged;
+ bool boolValueRet6 = NativeMethods.MarshalPointer_Out(out boolValue6);
+ if (!boolValueRet6)
+ {
+ ReportFailure("Method Marshal_Out[Managed Side],The return value is wrong", true, boolValueRet6);
+ }
+ if (boolValue6 != boolNative)
+ {
+ ReportFailure("Method Marshal_Out[Managed Side],The passed value is wrong", boolNative, boolValue6);
+ }
+
+ //Test Method7
+ bool boolValue7 = boolManaged;
+ bool boolValueRet7 = NativeMethods.Marshal_As_In(boolValue7);
+ if (!boolValueRet7)
+ {
+ ReportFailure("Method Marshal_As_In[Managed Side],The return value is wrong", true, boolValueRet1);
+ }
+
+ //TestMethod8
+ bool boolValue8 = boolManaged;
+ bool boolValueRet8 = NativeMethods.Marshal_As_InOut(boolValue8);
+ if (!boolValueRet8)
+ {
+ ReportFailure("Method Marshal_As_InOut[Managed Side],The return value is wrong", true, boolValueRet2);
+ }
+ if (boolValue8 != boolManaged)
+ {
+ ReportFailure("Method Marshal_As_InOut[Managed Side],The parameter value is changed", boolManaged, boolValue8);
+ }
+
+ //TestMethod9
+ bool boolValue9 = boolManaged;
+ bool boolValueRet9 = NativeMethods.Marshal_As_Out(boolValue9);
+ if (!boolValueRet9)
+ {
+ ReportFailure("Method Marshal_As_Out[Managed Side],The return value is wrong", true, boolValueRet3);
+ }
+ if (boolValue9 != boolManaged)
+ {
+ ReportFailure("Method Marshal_As_Out[Managed Side],The parameter value is changed", boolManaged, boolValue3);
+ }
+ return 100;
+ }
+}
diff --git a/tests/src/Interop/PrimitiveMarshalling/Bool/BoolTest.csproj b/tests/src/Interop/PrimitiveMarshalling/Bool/BoolTest.csproj
new file mode 100644
index 0000000000..29c96ada06
--- /dev/null
+++ b/tests/src/Interop/PrimitiveMarshalling/Bool/BoolTest.csproj
@@ -0,0 +1,49 @@
+<?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>BoolTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <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" />
+ <Compile Include="..\..\common\Assertion.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj">
+ <Project>{c8c0dc74-fac4-45b1-81fe-70c4808366e0}</Project>
+ <Name>CoreCLRTestLibrary</Name>
+ </ProjectReference>
+ <ProjectReference Include="CMakeLists.txt">
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project> \ No newline at end of file
diff --git a/tests/src/Interop/PrimitiveMarshalling/Bool/CMakeLists.txt b/tests/src/Interop/PrimitiveMarshalling/Bool/CMakeLists.txt
new file mode 100644
index 0000000000..9170660fc0
--- /dev/null
+++ b/tests/src/Interop/PrimitiveMarshalling/Bool/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required (VERSION 2.6)
+project (NativeBool)
+set(SOURCES BoolNative.cpp )
+
+# add the executable
+add_library (BoolNative SHARED ${SOURCES})
+
+#get_cmake_property(_variableNames VARIABLES)
+#foreach (_variableName ${_variableNames})
+# message(STATUS "${_variableName}=${${_variableName}}")
+#endforeach()
+
+
+#SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
+
+# add the install targets
+install (TARGETS BoolNative DESTINATION bin) \ No newline at end of file
diff --git a/tests/src/Interop/PrimitiveMarshalling/Bool/NativeMethodDef.cs b/tests/src/Interop/PrimitiveMarshalling/Bool/NativeMethodDef.cs
new file mode 100644
index 0000000000..d0b1eaab8b
--- /dev/null
+++ b/tests/src/Interop/PrimitiveMarshalling/Bool/NativeMethodDef.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Reflection;
+using System.Text;
+
+public class NativeMethods
+{
+
+ public const string NativeSharedBinaryName = "BoolNative";
+
+ [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)]
+ public static extern bool Marshal_In([In]bool boolValue);
+
+ [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)]
+ public static extern bool Marshal_InOut([In, Out]bool boolValue);
+
+ [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)]
+ public static extern bool Marshal_Out([Out]bool boolValue);
+
+ [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)]
+ public static extern bool MarshalPointer_In([In]ref bool pboolValue);
+
+ [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)]
+ public static extern bool MarshalPointer_InOut(ref bool pboolValue);
+
+ [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)]
+ public static extern bool MarshalPointer_Out(out bool pboolValue);
+
+ [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ public static extern bool Marshal_As_In(
+ [In, MarshalAs(UnmanagedType.U1)]bool boolValue);
+
+ [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ public static extern bool Marshal_As_InOut(
+ [In, Out, MarshalAs(UnmanagedType.U1)]bool boolValue);
+
+ [DllImport(NativeSharedBinaryName, CallingConvention = CallingConvention.StdCall)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ public static extern bool Marshal_As_Out(
+ [Out, MarshalAs(UnmanagedType.U1)]bool boolValue);
+}
diff --git a/tests/src/Interop/PrimitiveMarshalling/Bool/project.json b/tests/src/Interop/PrimitiveMarshalling/Bool/project.json
new file mode 100644
index 0000000000..51514fcf96
--- /dev/null
+++ b/tests/src/Interop/PrimitiveMarshalling/Bool/project.json
@@ -0,0 +1,33 @@
+{
+ "dependencies": {
+ "System.Diagnostics.Process": "4.0.0-beta-23302",
+ "System.IO": "4.0.10-beta-23302",
+ "System.IO.FileSystem": "4.0.0-beta-23302",
+ "System.IO.FileSystem.Primitives": "4.0.0-beta-23302",
+ "System.Runtime": "4.0.20-beta-23302",
+ "System.Runtime.Extensions": "4.0.10-beta-23302",
+ "System.Runtime.Handles": "4.0.0-beta-23302",
+ "System.Runtime.Loader": "4.0.0-beta-23302",
+ "System.Threading": "4.0.10-beta-23302",
+ "System.Globalization.Calendars": "4.0.0-beta-23302",
+ "System.Globalization": "4.0.10-beta-23302",
+ "System.Text.Encoding": "4.0.10-beta-23302",
+ "System.Runtime.InteropServices": "4.0.20-beta-23302",
+ "System.Collections": "4.0.10-beta-23302",
+ "System.Console": "4.0.0-beta-23302",
+ "System.Reflection": "4.0.10-beta-23302",
+ "System.Reflection.Primitives": "4.0.0-beta-23302",
+ "System.ComponentModel": "4.0.1-beta-23302",
+ "System.Xml.ReaderWriter": "4.0.11-beta-23302",
+ "System.Collections.NonGeneric": "4.0.1-beta-23302",
+ "System.Collections.Specialized": "4.0.1-beta-23302",
+ "System.Linq": "4.0.1-beta-23302",
+ "System.Linq.Queryable": "4.0.1-beta-23302",
+ "System.Xml.XmlSerializer": "4.0.11-beta-23302",
+ "System.Xml.XmlDocument": "4.0.1-beta-23302",
+ "System.Xml.XDocument": "4.0.11-beta-23302"
+ },
+ "frameworks": {
+ "dnxcore50": {}
+ }
+} \ No newline at end of file
diff --git a/tests/src/Interop/PrimitiveMarshalling/UIntPtr/CMakeLists.txt b/tests/src/Interop/PrimitiveMarshalling/UIntPtr/CMakeLists.txt
new file mode 100644
index 0000000000..a748623ab3
--- /dev/null
+++ b/tests/src/Interop/PrimitiveMarshalling/UIntPtr/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required (VERSION 2.6)
+project (UIntPtrNative)
+include_directories(${INC_PLATFORM_DIR})
+set(SOURCES UIntPtrNative.cpp )
+
+# add the executable
+add_library (UIntPtrNative SHARED ${SOURCES})
+
+# add the install targets
+install (TARGETS UIntPtrNative DESTINATION bin) \ No newline at end of file
diff --git a/tests/src/Interop/PrimitiveMarshalling/UIntPtr/PInvokeUIntPtrTest.cs b/tests/src/Interop/PrimitiveMarshalling/UIntPtr/PInvokeUIntPtrTest.cs
new file mode 100644
index 0000000000..cca97348cb
--- /dev/null
+++ b/tests/src/Interop/PrimitiveMarshalling/UIntPtr/PInvokeUIntPtrTest.cs
@@ -0,0 +1,59 @@
+using System.Runtime.InteropServices;
+using System;
+using System.Reflection;
+using System.Text;
+using CoreFXTestLibrary;
+
+class Test
+{
+ [DllImport(@"UIntPtrNative", CallingConvention = CallingConvention.StdCall)]
+ private static extern UIntPtr Marshal_In([In]UIntPtr uintPtr);
+
+ [DllImport(@"UIntPtrNative", CallingConvention = CallingConvention.StdCall)]
+ private static extern UIntPtr Marshal_InOut([In, Out]UIntPtr uintPtr);
+
+ [DllImport(@"UIntPtrNative", CallingConvention = CallingConvention.StdCall)]
+ private static extern UIntPtr Marshal_Out([Out]UIntPtr uintPtr);
+
+ [DllImport(@"UIntPtrNative", CallingConvention = CallingConvention.StdCall)]
+ private static extern UIntPtr MarshalPointer_In([In]ref UIntPtr puintPtr);
+
+ [DllImport(@"UIntPtrNative", CallingConvention = CallingConvention.StdCall)]
+ private static extern UIntPtr MarshalPointer_InOut(ref UIntPtr puintPtr);
+
+ [DllImport(@"UIntPtrNative", CallingConvention = CallingConvention.StdCall)]
+ private static extern UIntPtr MarshalPointer_Out(out UIntPtr puintPtr);
+
+
+ public static int Main(string[] args)
+ {
+ UIntPtr uintPtrManaged = (UIntPtr)1000;
+ UIntPtr uintPtrNative = (UIntPtr)2000;
+ UIntPtr uintPtrReturn = (UIntPtr)3000;
+
+ UIntPtr uintPtr1 = uintPtrManaged;
+ Assert.AreEqual(uintPtrReturn, Marshal_In(uintPtr1), "The return value is wrong");
+
+ UIntPtr uintPtr2 = uintPtrManaged;
+ Assert.AreEqual(uintPtrReturn, Marshal_InOut(uintPtr2), "The return value is wrong");
+ Assert.AreEqual(uintPtrManaged, uintPtr2, "The parameter value is changed");
+
+ UIntPtr uintPtr3 = uintPtrManaged;
+ Assert.AreEqual(uintPtrReturn, Marshal_Out(uintPtr3), "The return value is wrong");
+ Assert.AreEqual(uintPtrManaged, uintPtr3, "The parameter value is changed");
+
+ UIntPtr uintPtr4 = uintPtrManaged;
+ Assert.AreEqual(uintPtrReturn, MarshalPointer_In(ref uintPtr4), "The return value is wrong");
+ Assert.AreEqual(uintPtrManaged, uintPtr4, "The parameter value is changed");
+
+ UIntPtr uintPtr5 = uintPtrManaged;
+ Assert.AreEqual(uintPtrReturn, MarshalPointer_InOut(ref uintPtr5), "The return value is wrong");
+ Assert.AreEqual(uintPtrNative, uintPtr5, "The passed value is wrong");
+
+ UIntPtr uintPtr6 = uintPtrManaged;
+ Assert.AreEqual(uintPtrReturn, MarshalPointer_Out(out uintPtr6), "The return value is wrong");
+ Assert.AreEqual(uintPtrNative, uintPtr6, "The passed value is wrong");
+
+ return 100;
+ }
+} \ No newline at end of file
diff --git a/tests/src/Interop/PrimitiveMarshalling/UIntPtr/PInvokeUIntPtrTest.csproj b/tests/src/Interop/PrimitiveMarshalling/UIntPtr/PInvokeUIntPtrTest.csproj
new file mode 100644
index 0000000000..0f41315402
--- /dev/null
+++ b/tests/src/Interop/PrimitiveMarshalling/UIntPtr/PInvokeUIntPtrTest.csproj
@@ -0,0 +1,49 @@
+<?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>PInvokeUIntPtrTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <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="PInvokeUIntPtrTest.cs" />
+ <Compile Include="..\..\common\Assertion.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj">
+ <Project>{c8c0dc74-fac4-45b1-81fe-70c4808366e0}</Project>
+ <Name>CoreCLRTestLibrary</Name>
+ </ProjectReference>
+ <ProjectReference Include="CMakeLists.txt">
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project> \ No newline at end of file
diff --git a/tests/src/Interop/PrimitiveMarshalling/UIntPtr/UIntPtrNative.cpp b/tests/src/Interop/PrimitiveMarshalling/UIntPtr/UIntPtrNative.cpp
new file mode 100644
index 0000000000..e105f6cc70
--- /dev/null
+++ b/tests/src/Interop/PrimitiveMarshalling/UIntPtr/UIntPtrNative.cpp
@@ -0,0 +1,86 @@
+
+#include <xplatform.h>
+#include <stdio.h>
+
+UINT_PTR uintPtrManaged = 1000;
+UINT_PTR uintPtrNative = 2000;
+UINT_PTR uintPtrReturn = 3000;
+UINT_PTR uintPtrErrReturn = 4000;
+
+extern "C" DLL_EXPORT UINT_PTR WINAPI Marshal_In(/*[in]*/UINT_PTR uintPtr)
+{
+ //Check the input
+ if(uintPtr != uintPtrManaged)
+ {
+ printf("Error in Function Marshal_In(Native Client)\n");
+
+ //Return the error value instead if verification failed
+ return uintPtrErrReturn;
+ }
+
+ return uintPtrReturn;
+}
+
+extern "C" DLL_EXPORT UINT_PTR WINAPI Marshal_InOut(/*[In,Out]*/UINT_PTR uintPtr)
+{
+ //Check the input
+ if(uintPtr != uintPtrManaged)
+ {
+ printf("Error in Function Marshal_In(Native Client)\n");
+
+ //Return the error value instead if verification failed
+ return uintPtrErrReturn;
+ }
+
+ //In-Place Change
+ uintPtr = uintPtrNative;
+
+ //Return
+ return uintPtrReturn;
+}
+
+extern "C" DLL_EXPORT UINT_PTR WINAPI Marshal_Out(/*[Out]*/UINT_PTR uintPtr)
+{
+ uintPtr = uintPtrNative;
+
+ //Return
+ return uintPtrReturn;
+}
+
+extern "C" DLL_EXPORT UINT_PTR WINAPI MarshalPointer_In(/*[in]*/UINT_PTR *puintPtr)
+{
+ //Check the input
+ if(*puintPtr != uintPtrManaged)
+ {
+ printf("Error in Function Marshal_In(Native Client)\n");
+ //Return the error value instead if verification failed
+ return uintPtrErrReturn;
+ }
+
+ return uintPtrReturn;
+}
+
+extern "C" DLL_EXPORT UINT_PTR WINAPI MarshalPointer_InOut(/*[in,out]*/UINT_PTR *puintPtr)
+{
+ //Check the input
+ if(*puintPtr != uintPtrManaged)
+ {
+ printf("Error in Function Marshal_In(Native Client)\n");
+ //Return the error value instead if verification failed
+ return uintPtrErrReturn;
+ }
+
+ //In-Place Change
+ *puintPtr = uintPtrNative;
+
+ //Return
+ return uintPtrReturn;
+}
+
+extern "C" DLL_EXPORT UINT_PTR WINAPI MarshalPointer_Out(/*[out]*/ UINT_PTR *puintPtr)
+{
+ *puintPtr = uintPtrNative;
+
+ //Return
+ return uintPtrReturn;
+}
diff --git a/tests/src/Interop/PrimitiveMarshalling/UIntPtr/project.json b/tests/src/Interop/PrimitiveMarshalling/UIntPtr/project.json
new file mode 100644
index 0000000000..51514fcf96
--- /dev/null
+++ b/tests/src/Interop/PrimitiveMarshalling/UIntPtr/project.json
@@ -0,0 +1,33 @@
+{
+ "dependencies": {
+ "System.Diagnostics.Process": "4.0.0-beta-23302",
+ "System.IO": "4.0.10-beta-23302",
+ "System.IO.FileSystem": "4.0.0-beta-23302",
+ "System.IO.FileSystem.Primitives": "4.0.0-beta-23302",
+ "System.Runtime": "4.0.20-beta-23302",
+ "System.Runtime.Extensions": "4.0.10-beta-23302",
+ "System.Runtime.Handles": "4.0.0-beta-23302",
+ "System.Runtime.Loader": "4.0.0-beta-23302",
+ "System.Threading": "4.0.10-beta-23302",
+ "System.Globalization.Calendars": "4.0.0-beta-23302",
+ "System.Globalization": "4.0.10-beta-23302",
+ "System.Text.Encoding": "4.0.10-beta-23302",
+ "System.Runtime.InteropServices": "4.0.20-beta-23302",
+ "System.Collections": "4.0.10-beta-23302",
+ "System.Console": "4.0.0-beta-23302",
+ "System.Reflection": "4.0.10-beta-23302",
+ "System.Reflection.Primitives": "4.0.0-beta-23302",
+ "System.ComponentModel": "4.0.1-beta-23302",
+ "System.Xml.ReaderWriter": "4.0.11-beta-23302",
+ "System.Collections.NonGeneric": "4.0.1-beta-23302",
+ "System.Collections.Specialized": "4.0.1-beta-23302",
+ "System.Linq": "4.0.1-beta-23302",
+ "System.Linq.Queryable": "4.0.1-beta-23302",
+ "System.Xml.XmlSerializer": "4.0.11-beta-23302",
+ "System.Xml.XmlDocument": "4.0.1-beta-23302",
+ "System.Xml.XDocument": "4.0.11-beta-23302"
+ },
+ "frameworks": {
+ "dnxcore50": {}
+ }
+} \ No newline at end of file
diff --git a/tests/src/Interop/common/Assertion.cs b/tests/src/Interop/common/Assertion.cs
new file mode 100644
index 0000000000..dd2a76fc10
--- /dev/null
+++ b/tests/src/Interop/common/Assertion.cs
@@ -0,0 +1,811 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+// Note: Exception messages call ToString instead of Name to avoid MissingMetadataException when just outputting basic info
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace CoreFXTestLibrary
+{
+ /// <summary>
+ /// A collection of helper classes to test various conditions within
+ /// unit tests. If the condition being tested is not met, an exception
+ /// is thrown.
+ /// </summary>
+ public static class Assert
+ {
+ /// <summary>
+ /// Asserts that the given delegate throws an <see cref="ArgumentNullException"/> with the given parameter name.
+ /// </summary>
+ /// <param name="action">
+ /// The delagate of type <see cref="Action"/> to execute.
+ /// </param>
+ /// <param name="message">
+ /// A <see cref="String"/> containing additional information for when the assertion fails.
+ /// </param>
+ /// <param name="parameterName">
+ /// A <see cref="String"/> containing the parameter of name to check, <see langword="null"/> to skip parameter validation.
+ /// </param>
+ /// <returns>
+ /// The thrown <see cref="ArgumentNullException"/>.
+ /// </returns>
+ /// <exception cref="AssertFailedException">
+ /// <see cref="Exception"/> of type <see cref="ArgumentNullException"/> was not thrown.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <see cref="ArgumentException.ParamName"/> is not equal to <paramref name="parameterName"/> .
+ /// </exception>
+ public static ArgumentNullException ThrowsArgumentNullException(string parameterName, Action action, string message = null)
+ {
+ return ThrowsArgumentException<ArgumentNullException>(parameterName, action, message);
+ }
+
+ /// <summary>
+ /// Asserts that the given delegate throws an <see cref="ArgumentException"/> with the given parameter name.
+ /// </summary>
+ /// <param name="action">
+ /// The delagate of type <see cref="Action"/> to execute.
+ /// </param>
+ /// <param name="message">
+ /// A <see cref="String"/> containing additional information for when the assertion fails.
+ /// </param>
+ /// <param name="parameterName">
+ /// A <see cref="String"/> containing the parameter of name to check, <see langword="null"/> to skip parameter validation.
+ /// </param>
+ /// <returns>
+ /// The thrown <see cref="ArgumentException"/>.
+ /// </returns>
+ /// <exception cref="AssertFailedException">
+ /// <see cref="Exception"/> of type <see cref="ArgumentException"/> was not thrown.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <see cref="ArgumentException.ParamName"/> is not equal to <paramref name="parameterName"/> .
+ /// </exception>
+ public static ArgumentException ThrowsArgumentException(string parameterName, Action action, string message = null)
+ {
+ return ThrowsArgumentException<ArgumentException>(parameterName, action, message);
+ }
+
+ /// <summary>
+ /// Asserts that the given delegate throws an <see cref="ArgumentException"/> of type <typeparamref name="T"/> with the given parameter name.
+ /// </summary>
+ /// <param name="action">
+ /// The delagate of type <see cref="Action"/> to execute.
+ /// </param>
+ /// <param name="message">
+ /// A <see cref="String"/> containing additional information for when the assertion fails.
+ /// </param>
+ /// <param name="parameterName">
+ /// A <see cref="String"/> containing the parameter of name to check, <see langword="null"/> to skip parameter validation.
+ /// </param>
+ /// <returns>
+ /// The thrown <see cref="Exception"/>.
+ /// </returns>
+ /// <exception cref="AssertFailedException">
+ /// <see cref="Exception"/> of type <typeparam name="T"/> was not thrown.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <see cref="ArgumentException.ParamName"/> is not equal to <paramref name="parameterName"/> .
+ /// </exception>
+ public static T ThrowsArgumentException<T>(string parameterName, Action action, string message = null)
+ where T : ArgumentException
+ {
+ T exception = Throws<T>(action, message);
+
+#if DEBUG
+ // ParamName's not available on ret builds
+ if (parameterName != null)
+ Assert.AreEqual(parameterName, exception.ParamName, "Expected '{0}.ParamName' to be '{1}'. {2}", typeof(T), parameterName, message);
+#endif
+
+ return exception;
+ }
+
+ /// <summary>
+ /// Asserts that the given delegate throws an <see cref="AggregateException"/> with a base exception <see cref="Exception"/> of type <typeparam name="T" />.
+ /// </summary>
+ /// <param name="action">
+ /// The delagate of type <see cref="Action"/> to execute.
+ /// </param>
+ /// <param name="message">
+ /// A <see cref="String"/> containing additional information for when the assertion fails.
+ /// </param>
+ /// <returns>
+ /// The base <see cref="Exception"/> of the <see cref="AggregateException"/>.
+ /// </returns>
+ /// <exception cref="AssertFailedException">
+ /// <see cref="AggregateException"/> of was not thrown.
+ /// -or-
+ /// </para>
+ /// <see cref="AggregateException.GetBaseException()"/> is not of type <typeparam name="TBase"/>.
+ /// </exception>
+ public static TBase ThrowsAggregateException<TBase>(Action action, string message = "") where TBase : Exception
+ {
+ AggregateException exception = Throws<AggregateException>(action, message);
+
+ Exception baseException = exception.GetBaseException();
+ if (baseException == null)
+ Assert.Fail("Expected 'AggregateException.GetBaseException()' to be '{0}', however it is null. {1}", typeof(TBase), message);
+
+ if (baseException.GetType() != typeof(TBase))
+ Assert.Fail("Expected 'AggregateException.GetBaseException()', to be '{0}', however, '{1}' is. {2}", typeof(TBase), baseException.GetType(), message);
+
+ return (TBase)baseException;
+ }
+
+ /// <summary>
+ /// Asserts that the given delegate throws an <see cref="Exception"/> of type <typeparam name="T" />.
+ /// </summary>
+ /// <param name="action">
+ /// The delagate of type <see cref="Action"/> to execute.
+ /// </param>
+ /// <param name="format">
+ /// A <see cref="String"/> containing format information for when the assertion fails.
+ /// </param>
+ /// <param name="args">
+ /// An <see cref="Array"/> of arguments to be formatted.
+ /// </param>
+ /// <returns>
+ /// The thrown <see cref="Exception"/>.
+ /// </returns>
+ /// <exception cref="AssertFailedException">
+ /// <see cref="Exception"/> of type <typeparam name="T"/> was not thrown.
+ /// </exception>
+ public static T Throws<T>(Action action, string format, params Object[] args) where T : Exception
+ {
+ return Throws<T>(action, String.Format(format, args));
+ }
+
+ /// <summary>
+ /// Asserts that the given delegate throws an <see cref="Exception"/> of type <typeparam name="T" />.
+ /// </summary>
+ /// <param name="action">
+ /// The delagate of type <see cref="Action"/> to execute.
+ /// </param>
+ /// <param name="message">
+ /// A <see cref="String"/> containing additional information for when the assertion fails.
+ /// </param>
+ /// <param name="options">
+ /// Specifies whether <see cref="Assert.Throws{T}"/> should require an exact type match when comparing the expected exception type with the thrown exception. The default is <see cref="AssertThrowsOptions.None"/>.
+ /// </param>
+ /// <returns>
+ /// The thrown <see cref="Exception"/>.
+ /// </returns>
+ /// <exception cref="AssertFailedException">
+ /// <see cref="Exception"/> of type <typeparam name="T"/> was not thrown.
+ /// </exception>
+ public static T Throws<T>(Action action, string message = "", AssertThrowsOptions options = AssertThrowsOptions.None) where T : Exception
+ {
+ Exception exception = RunWithCatch(action);
+
+ if (exception == null)
+ Assert.Fail("Expected '{0}' to be thrown. {1}", typeof(T).ToString(), message);
+
+ if (!IsOfExceptionType<T>(exception, options))
+ Assert.Fail("Expected '{0}' to be thrown, however '{1}' was thrown. {2}", typeof(T), exception.GetType(), message);
+
+ return (T)exception;
+ }
+
+ /// <summary>
+ /// Asserts that the given async delegate throws an <see cref="Exception"/> of type <typeparam name="T".
+ /// </summary>
+ /// <param name="action">
+ /// The delagate of type <see cref="Func{}"/> to execute.
+ /// </param>
+ /// <param name="message">
+ /// A <see cref="String"/> containing additional information for when the assertion fails.
+ /// </param>
+ /// <param name="options">
+ /// Specifies whether <see cref="Assert.Throws{T}"/> should require an exact type match when comparing the expected exception type with the thrown exception. The default is <see cref="AssertThrowsOptions.None"/>.
+ /// </param>
+ /// <returns>
+ /// The thrown <see cref="Exception"/>.
+ /// </returns>
+ /// <exception cref="AssertFailedException">
+ /// <see cref="Exception"/> of type <typeparam name="T"/> was not thrown.
+ /// </exception>
+ public static async Task<T> ThrowsAsync<T>(Func<Task> action, string message = "", AssertThrowsOptions options = AssertThrowsOptions.None) where T : Exception
+ {
+ Exception exception = await RunWithCatchAsync(action);
+
+ if (exception == null)
+ Assert.Fail("Expected '{0}' to be thrown. {1}", typeof(T).ToString(), message);
+
+ if (!IsOfExceptionType<T>(exception, options))
+ Assert.Fail("Expected '{0}' to be thrown, however '{1}' was thrown. {2}", typeof(T), exception.GetType(), message);
+
+ return (T)exception;
+ }
+
+ /// <summary>
+ /// Asserts that the given async delegate throws an <see cref="Exception"/> of type <typeparam name="T" /> and <see cref="Exception.InnerException"/>
+ /// returns an <see cref="Exception"/> of type <typeparam name="TInner" />.
+ /// </summary>
+ /// <param name="action">
+ /// The delagate of type <see cref="Action"/> to execute.
+ /// </param>
+ /// <param name="message">
+ /// A <see cref="String"/> containing additional information for when the assertion fails.
+ /// </param>
+ /// <param name="options">
+ /// Specifies whether <see cref="Assert.Throws{T}"/> should require an exact type match when comparing the expected exception type with the thrown exception. The default is <see cref="AssertThrowsOptions.None"/>.
+ /// </param>
+ /// <returns>
+ /// The thrown inner <see cref="Exception"/>.
+ /// </returns>
+ /// <exception cref="AssertFailedException">
+ /// <see cref="Exception"/> of type <typeparam name="T"/> was not thrown.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <see cref="Exception.InnerException"/> is not of type <typeparam name="TInner"/>.
+ /// </exception>
+ public static TInner Throws<T, TInner>(Action action, string message = "", AssertThrowsOptions options = AssertThrowsOptions.None)
+ where T : Exception
+ where TInner : Exception
+ {
+ T outerException = Throws<T>(action, message, options);
+
+ if (outerException.InnerException == null)
+ Assert.Fail("Expected '{0}.InnerException' to be '{1}', however it is null. {2}", typeof(T), typeof(TInner), message);
+
+ if (!IsOfExceptionType<TInner>(outerException.InnerException, options))
+ Assert.Fail("Expected '{0}.InnerException', to be '{1}', however, '{2}' is. {3}", typeof(T), typeof(TInner), outerException.InnerException.GetType(), message);
+
+ return (TInner)outerException.InnerException;
+ }
+
+
+ /// <summary>
+ /// Tests whether the specified condition is true and throws an exception
+ /// if the condition is false.
+ /// </summary>
+ /// <param name="condition">The condition the test expects to be true.</param>
+ /// <param name="message">
+ /// The message to include in the exception when <paramref name="condition"/>
+ /// is false. The message is shown in test results.
+ /// </param>
+ /// <exception cref="AssertFailedException">
+ /// Thrown if <paramref name="condition"/> is false.
+ /// </exception>
+ public static void IsTrue(bool condition, string format, params Object[] args)
+ {
+ if (!condition)
+ {
+ Assert.HandleFail("Assert.IsTrue", String.Format(format, args));
+ }
+ }
+
+ /// <summary>
+ /// Tests whether the specified condition is true and throws an exception
+ /// if the condition is false.
+ /// </summary>
+ /// <param name="condition">The condition the test expects to be true.</param>
+ /// <param name="message">
+ /// The message to include in the exception when <paramref name="condition"/>
+ /// is false. The message is shown in test results.
+ /// </param>
+ /// <exception cref="AssertFailedException">
+ /// Thrown if <paramref name="condition"/> is false.
+ /// </exception>
+ public static void IsTrue(bool condition, string message = "")
+ {
+ if (!condition)
+ {
+ Assert.HandleFail("Assert.IsTrue", message);
+ }
+ }
+
+ /// <summary>
+ /// Tests whether the specified condition is false and throws an exception
+ /// if the condition is true.
+ /// </summary>
+ /// <param name="condition">The condition the test expects to be false.</param>
+ /// <param name="message">
+ /// The message to include in the exception when <paramref name="condition"/>
+ /// is true. The message is shown in test results.
+ /// </param>
+ /// <exception cref="AssertFailedException">
+ /// Thrown if <paramref name="condition"/> is true.
+ /// </exception>
+ public static void IsFalse(bool condition, string message = "")
+ {
+ if (condition)
+ {
+ Assert.HandleFail("Assert.IsFalse", message);
+ }
+ }
+
+ /// <summary>
+ /// Tests whether the specified condition is false and throws an exception
+ /// if the condition is true.
+ /// </summary>
+ /// <param name="condition">The condition the test expects to be false.</param>
+ /// <param name="message">
+ /// The message to include in the exception when <paramref name="condition"/>
+ /// is true. The message is shown in test results.
+ /// </param>
+ /// <exception cref="AssertFailedException">
+ /// Thrown if <paramref name="condition"/> is true.
+ /// </exception>
+ public static void IsFalse(bool condition, string format, params Object[] args)
+ {
+ IsFalse(condition, String.Format(format, args));
+ }
+
+ /// <summary>
+ /// Tests whether the specified object is null and throws an exception
+ /// if it is not.
+ /// </summary>
+ /// <param name="value">The object the test expects to be null.</param>
+ /// <param name="message">
+ /// The message to include in the exception when <paramref name="value"/>
+ /// is not null. The message is shown in test results.
+ /// </param>
+ /// <exception cref="AssertFailedException">
+ /// Thrown if <paramref name="value"/> is not null.
+ /// </exception>
+ public static void IsNull(object value, string message = "")
+ {
+ if (value != null)
+ {
+ Assert.HandleFail("Assert.IsNull", message);
+ }
+ }
+
+ /// <summary>
+ /// Tests whether the specified object is null and throws an exception
+ /// if it is not.
+ /// </summary>
+ /// <param name="value">The object the test expects to be null.</param>
+ /// <param name="message">
+ /// The message to include in the exception when <paramref name="value"/>
+ /// is not null. The message is shown in test results.
+ /// </param>
+ /// <exception cref="AssertFailedException">
+ /// Thrown if <paramref name="value"/> is not null.
+ /// </exception>
+ public static void IsNull(object value, string format, params Object[] args)
+ {
+ IsNull(value, String.Format(format, args));
+ }
+
+ /// <summary>
+ /// Tests whether the specified object is non-null and throws an exception
+ /// if it is null.
+ /// </summary>
+ /// <param name="value">The object the test expects not to be null.</param>
+ /// <param name="message">
+ /// The message to include in the exception when <paramref name="value"/>
+ /// is null. The message is shown in test results.
+ /// </param>
+ /// <exception cref="AssertFailedException">
+ /// Thrown if <paramref name="value"/> is null.
+ /// </exception>
+ public static void IsNotNull(object value, string message = "")
+ {
+ if (value == null)
+ {
+ Assert.HandleFail("Assert.IsNotNull", message);
+ }
+ }
+
+ /// <summary>
+ /// Tests whether the expected object is equal to the actual object and
+ /// throws an exception if it is not.
+ /// </summary>
+ /// <param name="notExpected">Expected object.</param>
+ /// <param name="actual">Actual object.</param>
+ /// <param name="message">Message to display upon failure.</param>
+ public static void AreEqual<T>(T expected, T actual, string message = "")
+ {
+ const string EXPECTED_MSG = @"Expected: [{1}]. Actual: [{2}]. {0}";
+
+ if (!Object.Equals(expected, actual))
+ {
+ string finalMessage = String.Format(EXPECTED_MSG, message, (object)expected ?? "NULL", (object)actual ?? "NULL");
+ Assert.HandleFail("Assert.AreEqual", finalMessage);
+ }
+ }
+
+ /// <summary>
+ /// Tests whether the expected object is equal to the actual object and
+ /// throws an exception if it is not.
+ /// </summary>
+ /// <param name="notExpected">Expected object.</param>
+ /// <param name="actual">Actual object.</param>
+ /// <param name="message">Message to display upon failure.</param>
+ public static void AreEqual<T>(T expected, T actual, string format, params Object[] args)
+ {
+ AreEqual<T>(expected, actual, String.Format(format, args));
+ }
+
+ /// <summary>
+ /// Tests whether the expected object is equal to the actual object and
+ /// throws an exception if it is not.
+ /// </summary>
+ /// <param name="notExpected">Expected object that we do not want it to be.</param>
+ /// <param name="actual">Actual object.</param>
+ /// <param name="message">Message to display upon failure.</param>
+ public static void AreNotEqual<T>(T notExpected, T actual, string message = "")
+ {
+ if (Object.Equals(notExpected, actual))
+ {
+ String finalMessage =
+ String.Format(@"Expected any value except:[{1}]. Actual:[{2}]. {0}",
+ message, notExpected, actual);
+
+ Assert.HandleFail("Assert.AreNotEqual", finalMessage);
+ }
+ }
+
+ /// <summary>
+ /// Tests whether the expected object is equal to the actual object and
+ /// throws an exception if it is not.
+ /// </summary>
+ /// <param name="notExpected">Expected object that we do not want it to be.</param>
+ /// <param name="actual">Actual object.</param>
+ /// <param name="message">Message to display upon failure.</param>
+ public static void AreNotEqual<T>(T notExpected, T actual, string format, params Object[] args)
+ {
+ AreNotEqual<T>(notExpected, actual, String.Format(format, args));
+ }
+
+ /// <summary>
+ /// Tests whether the two lists are the same length and contain the same objects (using Object.Equals()) in the same order and
+ /// throws an exception if it is not.
+ /// </summary>
+ /// <param name="expected">Expected list.</param>
+ /// <param name="actual">Actual list.</param>
+ /// <param name="message">Message to display upon failure.</param>
+ public static void AreAllEqual<T>(T[] expected, T[] actual, string message = "")
+ {
+ Assert.AreEqual(expected.Length, actual.Length, message);
+
+ for (int i = 0; i < expected.Length; i++)
+ Assert.AreEqual<T>(expected[i], actual[i], message);
+ }
+
+ /// <summary>
+ /// Tests whether the two lists are the same length and contain the same objects (using Object.Equals()) in the same order and
+ /// throws an exception if it is not.
+ /// </summary>
+ /// <param name="expected">Expected list.</param>
+ /// <param name="actual">Actual list.</param>
+ /// <param name="message">Message to display upon failure.</param>
+ public static void AreAllEqual<T>(T[] expected, T[] actual, string format, params Object[] args)
+ {
+ AreAllEqual<T>(expected, actual, String.Format(format, args));
+ }
+
+ /// <summary>
+ /// Tests whether the two lists are the same length and contain the same objects (using Object.Equals()) (but not necessarily in the same order) and
+ /// throws an exception if it is not.
+ /// </summary>
+ /// <param name="expected">Expected list.</param>
+ /// <param name="actual">Actual list.</param>
+ /// <param name="message">Message to display upon failure.</param>
+ public static void AreAllEqualUnordered<T>(T[] expected, T[] actual)
+ {
+ Assert.AreEqual(expected.Length, actual.Length);
+
+ int count = expected.Length;
+ bool[] removedFromActual = new bool[count];
+ for (int i = 0; i < count; i++)
+ {
+ T item1 = expected[i];
+ bool foundMatch = false;
+ for (int j = 0; j < count; j++)
+ {
+ if (!removedFromActual[j])
+ {
+ T item2 = actual[j];
+ if ((item1 == null && item2 == null) || (item1 != null && item1.Equals(item2)))
+ {
+ foundMatch = true;
+ removedFromActual[j] = true;
+ break;
+ }
+ }
+ }
+ if (!foundMatch)
+ Assert.HandleFail("Assert.AreAllEqualUnordered", "First array has element not found in second array: " + item1);
+ }
+ return;
+ }
+
+ /// <summary>
+ /// Tests whether the two enumerables are the same length and contain the same objects (using Object.Equals()) in the same order and
+ /// throws an exception if it is not.
+ /// </summary>
+ /// <param name="expected">Expected enumerables.</param>
+ /// <param name="actual">Actual enumerables.</param>
+ /// <param name="message">Message to display upon failure.</param>
+ public static void AreAllEqual<T>(IEnumerable<T> expected, IEnumerable<T> actual, string message = "")
+ {
+ AreAllEqual(CopyToArray(expected), CopyToArray(actual), message);
+ }
+
+ /// <summary>
+ /// Tests whether the two enumerables are the same length and contain the same objects (using Object.Equals()) (but not necessarily
+ /// in the same order) and throws an exception if it is not.
+ /// </summary>
+ /// <param name="expected">Expected enumerable.</param>
+ /// <param name="actual">Actual enumerable.</param>
+ /// <param name="message">Message to display upon failure.</param>
+ public static void AreAllEqualUnordered<T>(IEnumerable<T> expected, IEnumerable<T> actual, string message = "")
+ {
+ AreAllEqualUnordered(CopyToArray(expected), CopyToArray(actual), message);
+ }
+
+ /// <summary>
+ /// Iterates through an IEnumerable to generate an array of elements. The rational for using this instead of
+ /// System.Linq.ToArray is that this will not require a dependency on System.Linq.dll
+ /// </summary>
+ private static T[] CopyToArray<T>(IEnumerable<T> source)
+ {
+ T[] items = new T[4];
+ int count = 0;
+
+ if (source == null)
+ return null;
+
+ foreach (var item in source)
+ {
+ if (items.Length == count)
+ {
+ var newItems = new T[checked(count * 2)];
+ Array.Copy(items, 0, newItems, 0, count);
+ items = newItems;
+ }
+
+ items[count] = item;
+ count++;
+ }
+
+ if (items.Length == count)
+ return items;
+
+ var finalItems = new T[count];
+ Array.Copy(items, 0, finalItems, 0, count);
+ return finalItems;
+ }
+
+
+ /// <summary>
+ /// Tests whether the specified objects both refer to the same object and
+ /// throws an exception if the two inputs do not refer to the same object.
+ /// </summary>
+ /// <param name="expected">
+ /// The first object to compare. This is the value the test expects.
+ /// </param>
+ /// <param name="actual">
+ /// The second object to compare. This is the value produced by the code under test.
+ /// </param>
+ /// <exception cref="AssertFailedException">
+ /// Thrown if <paramref name="expected"/> does not refer to the same object
+ /// as <paramref name="actual"/>.
+ /// </exception>
+ static public void AreSame(object expected, object actual)
+ {
+ Assert.AreSame(expected, actual, string.Empty);
+ }
+
+ /// <summary>
+ /// Tests whether the specified objects both refer to the same object and
+ /// throws an exception if the two inputs do not refer to the same object.
+ /// </summary>
+ /// <param name="expected">
+ /// The first object to compare. This is the value the test expects.
+ /// </param>
+ /// <param name="actual">
+ /// The second object to compare. This is the value produced by the code under test.
+ /// </param>
+ /// <param name="message">
+ /// The message to include in the exception when <paramref name="actual"/>
+ /// is not the same as <paramref name="expected"/>. The message is shown
+ /// in test results.
+ /// </param>
+ /// <exception cref="AssertFailedException">
+ /// Thrown if <paramref name="expected"/> does not refer to the same object
+ /// as <paramref name="actual"/>.
+ /// </exception>
+ static public void AreSame(object expected, object actual, string message)
+ {
+ if (!Object.ReferenceEquals(expected, actual))
+ {
+ string finalMessage = message;
+
+ ValueType valExpected = expected as ValueType;
+ if (valExpected != null)
+ {
+ ValueType valActual = actual as ValueType;
+ if (valActual != null)
+ {
+ finalMessage = message == null ? String.Empty : message;
+ }
+ }
+
+ Assert.HandleFail("Assert.AreSame", finalMessage);
+ }
+ }
+
+ /// <summary>
+ /// Tests whether the specified objects refer to different objects and
+ /// throws an exception if the two inputs refer to the same object.
+ /// </summary>
+ /// <param name="notExpected">
+ /// The first object to compare. This is the value the test expects not
+ /// to match <paramref name="actual"/>.
+ /// </param>
+ /// <param name="actual">
+ /// The second object to compare. This is the value produced by the code under test.
+ /// </param>
+ /// <exception cref="AssertFailedException">
+ /// Thrown if <paramref name="notExpected"/> refers to the same object
+ /// as <paramref name="actual"/>.
+ /// </exception>
+ static public void AreNotSame(object notExpected, object actual)
+ {
+ Assert.AreNotSame(notExpected, actual, string.Empty);
+ }
+
+ /// <summary>
+ /// Tests whether the specified objects refer to different objects and
+ /// throws an exception if the two inputs refer to the same object.
+ /// </summary>
+ /// <param name="notExpected">
+ /// The first object to compare. This is the value the test expects not
+ /// to match <paramref name="actual"/>.
+ /// </param>
+ /// <param name="actual">
+ /// The second object to compare. This is the value produced by the code under test.
+ /// </param>
+ /// <param name="message">
+ /// The message to include in the exception when <paramref name="actual"/>
+ /// is the same as <paramref name="notExpected"/>. The message is shown in
+ /// test results.
+ /// </param>
+ /// <exception cref="AssertFailedException">
+ /// Thrown if <paramref name="notExpected"/> refers to the same object
+ /// as <paramref name="actual"/>.
+ /// </exception>
+ static public void AreNotSame(object notExpected, object actual, string message)
+ {
+ if (Object.ReferenceEquals(notExpected, actual))
+ {
+ Assert.HandleFail("Assert.AreNotSame", message);
+ }
+ }
+
+ /// <summary>
+ /// Throws an AssertFailedException.
+ /// </summary>
+ /// <exception cref="AssertFailedException">
+ /// Always thrown.
+ /// </exception>
+ public static void Fail()
+ {
+ Assert.HandleFail("Assert.Fail", "");
+ }
+
+ /// <summary>
+ /// Throws an AssertFailedException.
+ /// </summary>
+ /// <param name="message">
+ /// The message to include in the exception. The message is shown in
+ /// test results.
+ /// </param>
+ /// <exception cref="AssertFailedException">
+ /// Always thrown.
+ /// </exception>
+ public static void Fail(string message, params object[] args)
+ {
+ string exceptionMessage = args.Length == 0 ? message : string.Format(message, args);
+ Assert.HandleFail("Assert.Fail", exceptionMessage);
+ }
+
+ /// <summary>
+ /// Helper function that creates and throws an exception.
+ /// </summary>
+ /// <param name="assertionName">name of the assertion throwing an exception.</param>
+ /// <param name="message">message describing conditions for assertion failure.</param>
+ /// <param name="parameters">The parameters.</param>
+ /// TODO: Modify HandleFail to take in parameters
+ internal static void HandleFail(string assertionName, string message)
+ {
+ // change this to use AssertFailedException
+ throw new AssertTestException(assertionName + ": " + message);
+ }
+
+
+ [Obsolete("Did you mean to call Assert.AreEqual()")]
+ public static new bool Equals(Object o1, Object o2)
+ {
+ Assert.Fail("Don\u2019t call this.");
+ throw new Exception();
+ }
+
+ private static bool IsOfExceptionType<T>(Exception thrown, AssertThrowsOptions options)
+ {
+ if ((options & AssertThrowsOptions.AllowDerived) == AssertThrowsOptions.AllowDerived)
+ return thrown is T;
+
+ return thrown.GetType() == typeof(T);
+ }
+
+ private static Exception RunWithCatch(Action action)
+ {
+ try
+ {
+ action();
+ return null;
+ }
+ catch (Exception ex)
+ {
+ return ex;
+ }
+ }
+
+ private static async Task<Exception> RunWithCatchAsync(Func<Task> action)
+ {
+ try
+ {
+ await action();
+ return null;
+ }
+ catch (Exception ex)
+ {
+ return ex;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Exception raised by the Assert on Fail
+ /// </summary>
+ public class AssertTestException : Exception
+ {
+ public AssertTestException(string message)
+ : base(message)
+ {
+ }
+
+ public AssertTestException()
+ : base()
+ {
+ }
+ }
+
+ public static class ExceptionAssert
+ {
+ public static void Throws<T>(String message, Action a) where T : Exception
+ {
+ Assert.Throws<T>(a, message);
+ }
+ }
+
+ /// <summary>
+ /// Specifies whether <see cref="Assert.Throws{T}"/> should require an exact type match when comparing the expected exception type with the thrown exception.
+ /// </summary>
+ [Flags]
+ public enum AssertThrowsOptions
+ {
+ /// <summary>
+ /// Specifies that <see cref="Assert.Throws{T}"/> should require an exact type
+ /// match when comparing the specified exception type with the throw exception.
+ /// </summary>
+ None = 0,
+
+ /// <summary>
+ /// Specifies that <see cref="Assert.Throws{T}"/> should not require an exact type
+ /// match when comparing the specified exception type with the thrown exception.
+ /// </summary>
+ AllowDerived = 1,
+ }
+}
diff --git a/tests/src/Interop/common/types.h b/tests/src/Interop/common/types.h
new file mode 100644
index 0000000000..575fc320ca
--- /dev/null
+++ b/tests/src/Interop/common/types.h
@@ -0,0 +1,55 @@
+
+
+#ifndef _INTEROP_TYPES__H
+#define _INTEROP_TYPES__H
+
+#define INT_MIN (-2147483647 - 1)
+
+typedef char16_t WCHAR;
+typedef unsigned long DWORD;
+typedef int BOOL;
+typedef WCHAR *LPWSTR, *PWSTR;
+typedef const WCHAR *LPCWSTR, *PCWSTR;
+
+#ifdef UNICODE
+typedef WCHAR TCHAR;
+#else // ANSI
+typedef char TCHAR;
+#endif // UNICODE
+
+typedef char* LPSTR;
+typedef const char* LPCSTR;
+typedef TCHAR* LPTSTR;
+typedef const TCHAR* LPCTSTR;
+typedef void* FARPROC;
+typedef void* HMODULE;
+typedef void* ULONG_PTR;
+typedef unsigned error_t;
+typedef void* LPVOID;
+typedef char BYTE;
+typedef WCHAR OLECHAR;
+
+typedef unsigned int UINT_PTR;
+
+typedef unsigned long ULONG64;
+typedef double DOUBLE;
+typedef float FLOAT;
+typedef signed long LONG64, *PLONG64;
+typedef int INT, *LPINT;
+typedef unsigned int UINT;
+typedef char CHAR, *PCHAR;
+typedef unsigned short USHORT;
+typedef signed short SHORT;
+typedef unsigned short WORD, *PWORD, *LPWORD;
+
+typedef int* DWORD_PTR;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#endif //_INTEROP_TYPES__H \ No newline at end of file
diff --git a/tests/src/Interop/common/xplatform.h b/tests/src/Interop/common/xplatform.h
new file mode 100644
index 0000000000..3d30f0b75b
--- /dev/null
+++ b/tests/src/Interop/common/xplatform.h
@@ -0,0 +1,190 @@
+#ifndef __XPLAT_H__
+#define __XPLAT_H__
+
+// common headers
+#include <stdio.h>
+#include <memory.h>
+#include <stdlib.h>
+
+// This macro is used to standardize the wide character string literals between UNIX and Windows.
+// Unix L"" is UTF32, and on windows it's UTF16. Because of built-in assumptions on the size
+// of string literals, it's important to match behaviour between Unix and Windows. Unix will be defined
+// as u"" (char16_t)
+#ifdef _WIN32
+#define W(str) L##str
+#else // !_WIN32
+#define W(str) u##str
+#endif //_WIN32
+
+
+// include
+#ifdef _WIN32
+ #include <windows.h>
+ #include <wchar.h>
+ #include <tchar.h>
+#else
+ #include "types.h"
+#endif
+
+
+// dllexport
+#if defined _WIN32
+#define DLL_EXPORT __declspec(dllexport)
+#else //!_Win32
+#if __GNUC__ >= 4
+#define DLL_EXPORT __attribute__ ((visibility ("default")))
+#else
+#define DLL_EXPORT
+#endif
+
+#endif //_WIN32
+
+
+#define WINAPI _cdecl
+#ifndef __stdcall
+#if __i386__
+#define __stdcall __attribute__((stdcall))
+#define _cdecl __attribute__((cdecl))
+#else
+#define __stdcall
+#define _cdecl
+#endif
+#endif
+
+
+
+
+
+// Ensure that both UNICODE and _UNICODE are set.
+#ifdef UNICODE
+#ifndef _UNICODE
+#define _UNICODE
+#endif
+#else
+#ifdef _UNICODE
+#define UNICODE
+#endif
+#endif
+
+
+// redirected functions
+#ifdef UNICODE
+#define _tcslen wcslen
+#define _tcsncmp wcsncmp
+#else
+#define _tcslen strlen
+#define _tcsncmp strncmp
+#endif // UNICODE
+
+
+
+// redirected types not-windows only
+#ifndef _WIN32
+
+typedef union tagCY {
+ struct {
+ unsigned long Lo;
+ long Hi;
+ };
+ long int64;
+} CY, CURRENCY;
+
+#define CoTaskMemAlloc(p) malloc(p)
+#define CoTaskMemFree(p) free(p)
+
+// function implementation
+size_t strncpy_s(char* strDest, size_t numberOfElements, const char *strSource, size_t count)
+{
+ return snprintf(strDest, count, "%s", strSource);
+}
+
+size_t strcpy_s(char *dest, size_t n, char const *src)
+{
+ return snprintf(dest, n, "%s", src);
+}
+
+void SysFreeString(char* str)
+{
+ free(str);
+}
+
+
+char* SysAllocString( const char* str)
+{
+ size_t nz = strlen(str);
+ char *cArr = (char*) malloc(nz);
+ memcpy(cArr, str, nz);
+ return cArr;
+}
+
+
+size_t wcslen(const WCHAR *str)
+{
+ int len;
+ if (!str) return 0;
+ len = 0;
+ while ('\0' != *(str + len)) len++;
+ return len;
+}
+
+WCHAR* SysAllocString(const WCHAR* str)
+{
+ size_t nz = wcslen(str);
+ nz *= 2;
+ WCHAR *cArr = (WCHAR*)malloc(nz);
+ memcpy(cArr, str, nz);
+ return cArr;
+}
+
+
+
+int wcsncpy_s(LPWSTR strDestination, size_t size1, LPCWSTR strSource, size_t size2)
+{
+ int cnt;
+ // copy sizeInBytes bytes of strSource into strDestination
+ if (NULL == strDestination || NULL == strSource) return 1;
+
+ cnt = 0;
+ while (cnt < size1 && '\0' != strSource[cnt])
+ {
+ strDestination[cnt] = strSource[cnt];
+ cnt++;
+ }
+ strDestination[cnt] = '\0';
+ return 0;
+}
+
+int wcsncpy_s(LPWSTR strDestination, size_t size1, LPCWSTR strSource)
+{
+ return wcsncpy_s(strDestination, size1, strSource, 0);
+
+}
+
+int wmemcmp(LPWSTR str1, LPWSTR str2,size_t len)
+{
+ // < 0 str1 less than str2
+ // 0 str1 identical to str2
+ // > 0 str1 greater than str2
+
+ if (NULL == str1 && NULL != str2) return -1;
+ if (NULL != str1 && NULL == str2) return 1;
+ if (NULL == str1 && NULL == str2) return 0;
+
+ while (*str1 == *str2 && '\0' != *str1 && '\0' != *str2 && len--!= 0)
+ {
+ str1++;
+ str2++;
+ }
+
+ if ('\0' == *str1 && '\0' == *str2) return 0;
+
+ if ('\0' != *str1) return -1;
+ if ('\0' != *str2) return 1;
+
+ return (*str1 > *str2) ? 1 : -1;
+}
+
+
+#endif //!_Win32
+
+#endif // __XPLAT_H__