summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJeremy Koritzinsky <jkoritzinsky@gmail.com>2019-01-09 15:03:43 -0800
committerGitHub <noreply@github.com>2019-01-09 15:03:43 -0800
commit9b3ace68d678b52ccff163fdcf1332be20ecd17f (patch)
tree5f7d85b799d871327e0dd33faa59f1c4385c4ba5 /tests
parent5c480a4a83339564d4631762c100a5e12ed87357 (diff)
downloadcoreclr-9b3ace68d678b52ccff163fdcf1332be20ecd17f.tar.gz
coreclr-9b3ace68d678b52ccff163fdcf1332be20ecd17f.tar.bz2
coreclr-9b3ace68d678b52ccff163fdcf1332be20ecd17f.zip
Add tests for our layout-class marshalling (#20867)
* Add simple test for the LayoutClassMarshaler (most of the code is already covered by the struct marshalling tests). * Add test for blittable layout class. * Apparently layout classes are passed by value when passed as struct fields instead of byref.
Diffstat (limited to 'tests')
-rw-r--r--tests/src/Interop/CMakeLists.txt1
-rw-r--r--tests/src/Interop/LayoutClass/CMakeLists.txt11
-rw-r--r--tests/src/Interop/LayoutClass/LayoutClassNative.cpp74
-rw-r--r--tests/src/Interop/LayoutClass/LayoutClassTest.cs227
-rw-r--r--tests/src/Interop/LayoutClass/LayoutClassTest.csproj38
5 files changed, 351 insertions, 0 deletions
diff --git a/tests/src/Interop/CMakeLists.txt b/tests/src/Interop/CMakeLists.txt
index 9e0bf85e9c..9784ea1c95 100644
--- a/tests/src/Interop/CMakeLists.txt
+++ b/tests/src/Interop/CMakeLists.txt
@@ -61,6 +61,7 @@ add_subdirectory(DllImportAttribute/ExeFile)
add_subdirectory(DllImportAttribute/FileNameContainDot)
add_subdirectory(DllImportAttribute/Simple)
add_subdirectory(ExecInDefAppDom)
+add_subdirectory(LayoutClass)
if(WIN32)
add_subdirectory(PInvoke/Attributes/LCID)
diff --git a/tests/src/Interop/LayoutClass/CMakeLists.txt b/tests/src/Interop/LayoutClass/CMakeLists.txt
new file mode 100644
index 0000000000..5626d66387
--- /dev/null
+++ b/tests/src/Interop/LayoutClass/CMakeLists.txt
@@ -0,0 +1,11 @@
+cmake_minimum_required (VERSION 2.6)
+project (LayoutClassNative)
+include_directories(${INC_PLATFORM_DIR})
+set(SOURCES LayoutClassNative.cpp )
+
+# add the executable
+add_library (LayoutClassNative SHARED ${SOURCES})
+target_link_libraries(LayoutClassNative ${LINK_LIBRARIES_ADDITIONAL})
+
+# add the install targets
+install (TARGETS LayoutClassNative DESTINATION bin)
diff --git a/tests/src/Interop/LayoutClass/LayoutClassNative.cpp b/tests/src/Interop/LayoutClass/LayoutClassNative.cpp
new file mode 100644
index 0000000000..3185040294
--- /dev/null
+++ b/tests/src/Interop/LayoutClass/LayoutClassNative.cpp
@@ -0,0 +1,74 @@
+#include "platformdefines.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <xplatform.h>
+
+typedef void *voidPtr;
+
+struct SeqClass
+{
+ int a;
+ bool b;
+ char* str;
+};
+
+struct ExpClass
+{
+ int a;
+ int extra; //padding needs to be added here as we have added 8 byte offset.
+ union
+ {
+ int i;
+ BOOL b;
+ double d;
+ } udata;
+};
+
+struct BlittableClass
+{
+ int a;
+};
+
+struct NestedLayoutClass
+{
+ SeqClass str;
+};
+
+extern "C"
+DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleSeqLayoutClassByRef(SeqClass *p)
+{
+ if((p->a != 0) || (p->b) || strcmp(p->str, "before") != 0)
+ {
+ printf("\np->a=%d, p->b=%s, p->str=%s", p->a, p->b ? "true" : "false", p->str);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+extern "C"
+DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleBlittableSeqLayoutClassByRef(BlittableClass *p)
+{
+ if(p->a != 10)
+ {
+ printf("\np->a=%d", p->a);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+extern "C"
+DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleExpLayoutClassByRef(ExpClass *p)
+{
+ if((p->a != 0) || (p->udata.i != 10))
+ {
+ printf("\np->a=%d, p->udata.i=%d\n",p->a,p->udata.i);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleNestedLayoutClassByValue(NestedLayoutClass v)
+{
+ return SimpleSeqLayoutClassByRef(&v.str);
+}
diff --git a/tests/src/Interop/LayoutClass/LayoutClassTest.cs b/tests/src/Interop/LayoutClass/LayoutClassTest.cs
new file mode 100644
index 0000000000..49984d52dc
--- /dev/null
+++ b/tests/src/Interop/LayoutClass/LayoutClassTest.cs
@@ -0,0 +1,227 @@
+using System;
+using System.Security;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+using TestLibrary;
+
+namespace PInvokeTests
+{
+ [StructLayout(LayoutKind.Sequential)]
+ public class SeqClass
+ {
+ public int a;
+ public bool b;
+ public string str;
+
+ public SeqClass(int _a, bool _b, string _str)
+ {
+ a = _a;
+ b = _b;
+ str = String.Concat(_str, "");
+ }
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ public class ExpClass
+ {
+ [FieldOffset(0)]
+ public DialogResult type;
+
+ [FieldOffset(8)]
+ public int i;
+
+ [FieldOffset(8)]
+ public bool b;
+
+ [FieldOffset(8)]
+ public double c;
+
+ public ExpClass(DialogResult t, int num)
+ {
+ type = t;
+ b = false;
+ c = num;
+ i = num;
+ }
+ public ExpClass(DialogResult t, double dnum)
+ {
+ type = t;
+ b = false;
+ i = 0;
+ c = dnum;
+ }
+ public ExpClass(DialogResult t, bool bnum)
+ {
+ type = t;
+ i = 0;
+ c = 0;
+ b = bnum;
+ }
+ }
+
+ public enum DialogResult
+ {
+ None = 0,
+ OK = 1,
+ Cancel = 2
+ }
+
+
+ [StructLayout(LayoutKind.Sequential)]
+ public class Blittable
+ {
+ public int a;
+
+ public Blittable(int _a)
+ {
+ a = _a;
+ }
+ }
+
+ public struct NestedLayout
+ {
+ public SeqClass value;
+ }
+
+ class StructureTests
+ {
+ [DllImport("LayoutClassNative")]
+ private static extern bool SimpleSeqLayoutClassByRef(SeqClass p);
+
+ [DllImport("LayoutClassNative")]
+ private static extern bool SimpleExpLayoutClassByRef(ExpClass p);
+
+ [DllImport("LayoutClassNative")]
+ private static extern bool SimpleNestedLayoutClassByValue(NestedLayout p);
+
+ [DllImport("LayoutClassNative")]
+ private static extern bool SimpleBlittableSeqLayoutClassByRef(Blittable p);
+
+ public static bool SequentialClass()
+ {
+ string s = "before";
+ bool retval = true;
+ SeqClass p = new SeqClass(0, false, s);
+
+ TestFramework.BeginScenario("Test #1 Pass a sequential layout class.");
+
+ try
+ {
+ retval = SimpleSeqLayoutClassByRef(p);
+
+ if (retval == false)
+ {
+ TestFramework.LogError("01", "PInvokeTests->SequentialClass : Unexpected error occured on unmanaged side");
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ TestFramework.LogError("04", "Unexpected exception: " + e.ToString());
+ retval = false;
+ }
+
+ return retval;
+ }
+
+ public static bool ExplicitClass()
+ {
+ ExpClass p;
+ bool retval = false;
+
+ TestFramework.BeginScenario("Test #2 Pass an explicit layout class.");
+
+ try
+ {
+ p = new ExpClass(DialogResult.None, 10);
+ retval = SimpleExpLayoutClassByRef(p);
+
+ if (retval == false)
+ {
+ TestFramework.LogError("01", "PInvokeTests->ExplicitClass : Unexpected error occured on unmanaged side");
+ return false;
+ }
+
+ }
+ catch (Exception e)
+ {
+ TestFramework.LogError("03", "Unexpected exception: " + e.ToString());
+ retval = false;
+ }
+
+ return retval;
+ }
+
+ public static bool BlittableClass()
+ {
+ bool retval = true;
+ Blittable p = new Blittable(10);
+
+ TestFramework.BeginScenario("Test #3 Pass a blittable sequential layout class.");
+
+ try
+ {
+ retval = SimpleBlittableSeqLayoutClassByRef(p);
+
+ if (retval == false)
+ {
+ TestFramework.LogError("01", "PInvokeTests->Blittable : Unexpected error occured on unmanaged side");
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ TestFramework.LogError("04", "Unexpected exception: " + e.ToString());
+ retval = false;
+ }
+
+ return retval;
+ }
+
+ public static bool NestedLayoutClass()
+ {
+ string s = "before";
+ bool retval = true;
+ SeqClass p = new SeqClass(0, false, s);
+ NestedLayout target = new NestedLayout
+ {
+ value = p
+ };
+
+ TestFramework.BeginScenario("Test #4 Nested sequential layout class in a structure.");
+
+ try
+ {
+ retval = SimpleNestedLayoutClassByValue(target);
+
+ if (retval == false)
+ {
+ TestFramework.LogError("01", "PInvokeTests->NestedLayoutClass : Unexpected error occured on unmanaged side");
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ TestFramework.LogError("04", "Unexpected exception: " + e.ToString());
+ retval = false;
+ }
+
+ return retval;
+ }
+
+ public static int Main(string[] argv)
+ {
+ bool retVal = true;
+
+ retVal = retVal && SequentialClass();
+ retVal = retVal && ExplicitClass();
+ retVal = retVal && BlittableClass();
+ retVal = retVal && NestedLayoutClass();
+
+ return (retVal ? 100 : 101);
+ }
+
+
+ }
+}
diff --git a/tests/src/Interop/LayoutClass/LayoutClassTest.csproj b/tests/src/Interop/LayoutClass/LayoutClassTest.csproj
new file mode 100644
index 0000000000..caf67cf064
--- /dev/null
+++ b/tests/src/Interop/LayoutClass/LayoutClassTest.csproj
@@ -0,0 +1,38 @@
+<?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>LayoutClassTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\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>