diff options
26 files changed, 4100 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__ diff --git a/tests/testsFailingOutsideWindows.txt b/tests/testsFailingOutsideWindows.txt index c6af7924f1..e74bd8618d 100644 --- a/tests/testsFailingOutsideWindows.txt +++ b/tests/testsFailingOutsideWindows.txt @@ -176,3 +176,4 @@ JIT/Methodical/Boxing/xlang/_orelsin_cs_il/_orelsin_cs_il.sh JIT/Methodical/Boxing/xlang/_relsin_cs_il/_relsin_cs_il.sh JIT/Methodical/localloc/call/call01_small/call01_small.sh JIT/Regression/Dev11/External/dev11_145295/CSharpPart/CSharpPart.sh +Interop/ArrayMarshalling/ByValArray/MarshalArrayByValTest/MarshalArrayByValTest.sh |