diff options
author | Aaron Robinson <arobins@microsoft.com> | 2018-09-10 17:24:49 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-10 17:24:49 -0700 |
commit | fc3378095f04946815e627a5ab70b528a898abe6 (patch) | |
tree | 44a1e2cd85c2a5c369bf6f754a0379a0751ccb66 /tests | |
parent | efd7220234aacef4af25a747797984d43ba5b961 (diff) | |
download | coreclr-fc3378095f04946815e627a5ab70b528a898abe6.tar.gz coreclr-fc3378095f04946815e627a5ab70b528a898abe6.tar.bz2 coreclr-fc3378095f04946815e627a5ab70b528a898abe6.zip |
Basic implementation for testing of COM activation of a .NET class (#19760)
* Rough outline of managed implementation for COM activation in SPCL
* Add property for finding interop common
Add property to exclude default assertion file
Display exe ExeLaunchProgram class is going to launch
* Add a native client for the NETServer
Consume the ExeLauncherProgram.cs file as a wrapper for the native test
* Update COM Server contracts to use 'int' instead of 'long'
* Complete symmetric testing coverage for .NET server and native client.
* Block EXE launch from running on non-Windows machines
* Disable COM testing in helix since it has issues on Windows Nano and there
is no way to determine that is the platform.
* Update tests based on CLSID mapping manifest approach.
Diffstat (limited to 'tests')
30 files changed, 2334 insertions, 227 deletions
diff --git a/tests/issues.targets b/tests/issues.targets index 2a3464237b..68f7472fe1 100644 --- a/tests/issues.targets +++ b/tests/issues.targets @@ -47,7 +47,11 @@ <ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/JitBlue/GitHub_11408/GitHub_11408/*"> <Issue>11408</Issue> </ExcludeList> - <ExcludeList Include="$(XunitTestBinBase)\Interop\COM\NETClients\Primitives\NETClientPrimitives\NETClientPrimitives.cmd"> + <!-- Disable COM tests since they don't properly run on Windows.Nano and at present there is no way to special case that OS flavor. --> + <ExcludeList Include="$(XunitTestBinBase)/Interop/COM/NETClients/Primitives/NETClientPrimitives/NETClientPrimitives.cmd"> + <Issue>19164</Issue> + </ExcludeList> + <ExcludeList Include="$(XunitTestBinBase)/Interop/COM/NativeClients/Primitives/Primitives.cmd"> <Issue>19164</Issue> </ExcludeList> </ItemGroup> @@ -671,11 +675,6 @@ <ExcludeList Include="$(XunitTestBinBase)/baseservices/varargs/varargsupport_r/*"> <Issue>Varargs supported on this platform</Issue> </ExcludeList> - - <!-- Disable COM tests since they don't properly run on Windows.Nano and at present there is no way to special case that OS flavor. --> - <ExcludeList Include="$(XunitTestBinBase)/Interop/COM/NETClients/Primitives/NETClientPrimitives/*"> - <Issue>Fails on Windows.Nano</Issue> - </ExcludeList> </ItemGroup> <!-- The following are tests that fail on non-Windows, which we must not run when building against packages --> @@ -786,6 +785,9 @@ <ExcludeList Include="$(XunitTestBinBase)/Interop/COM/NETClients/Primitives/NETClientPrimitives/NETClientPrimitives.*"> <Issue>by design Windows only</Issue> </ExcludeList> + <ExcludeList Include="$(XunitTestBinBase)/Interop/COM/NativeClients/Primitives/Primitives.*"> + <Issue>by design Windows only</Issue> + </ExcludeList> <ExcludeList Include="$(XunitTestBinBase)/JIT/Directed/IL/PInvokeTail/PInvokeTail/*"> <Issue>needs triage</Issue> </ExcludeList> diff --git a/tests/src/CLRTest.Execute.Batch.targets b/tests/src/CLRTest.Execute.Batch.targets index 4407010de4..1b1d36eb74 100644 --- a/tests/src/CLRTest.Execute.Batch.targets +++ b/tests/src/CLRTest.Execute.Batch.targets @@ -253,6 +253,11 @@ if defined DoLink ( </PropertyGroup> <PropertyGroup> <_CLRTestRunFile Condition="'$(CLRTestIsHosted)'=='true'">"%CORE_ROOT%\corerun.exe"</_CLRTestRunFile> + <BatchCopyCoreShimLocalCmds Condition="'$(CLRTestScriptLocalCoreShim)' == 'true'"><![CDATA[ +REM Local CoreShim requested - see MSBuild property 'CLRTestScriptLocalCoreShim' +ECHO Copying '%CORE_ROOT%\CoreShim.dll'... +COPY /y %CORE_ROOT%\CoreShim.dll . + ]]></BatchCopyCoreShimLocalCmds> <BatchCLRTestLaunchCmds><![CDATA[ IF NOT "%CLRCustomTestLauncher%"=="" ( set LAUNCHER=call %CLRCustomTestLauncher% %~dp0 @@ -260,6 +265,7 @@ IF NOT "%CLRCustomTestLauncher%"=="" ( set LAUNCHER=%_DebuggerFullPath% $(_CLRTestRunFile) ) $(BatchIlrtTestLaunchCmds) +$(BatchCopyCoreShimLocalCmds) ]]></BatchCLRTestLaunchCmds> <BatchCLRTestLaunchCmds Condition="'$(CLRTestKind)' == 'BuildAndRun'"> <![CDATA[ diff --git a/tests/src/Interop/CMakeLists.txt b/tests/src/Interop/CMakeLists.txt index 0107958aa5..76384b488d 100644 --- a/tests/src/Interop/CMakeLists.txt +++ b/tests/src/Interop/CMakeLists.txt @@ -33,6 +33,7 @@ add_subdirectory(DllImportAttribute/Simple) if(WIN32) add_subdirectory(COM/NativeServer) + add_subdirectory(COM/NativeClients/Primitives) add_subdirectory(IJW/FakeMscoree) # IJW isn't supported on ARM64 diff --git a/tests/src/Interop/COM/Activator/Activator.csproj b/tests/src/Interop/COM/Activator/Activator.csproj new file mode 100644 index 0000000000..51b89ebd40 --- /dev/null +++ b/tests/src/Interop/COM/Activator/Activator.csproj @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Interop.settings.targets))\Interop.settings.targets" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <AssemblyName>Activator</AssemblyName> + <SchemaVersion>2.0</SchemaVersion> + <OutputType>Exe</OutputType> + <ReferenceSystemPrivateCoreLib>true</ReferenceSystemPrivateCoreLib> + + <!-- Test unsupported outside of windows --> + <TestUnsupportedOutsideWindows>true</TestUnsupportedOutsideWindows> + <DisableProjectBuild Condition="'$(TargetsUnix)' == 'true'">true</DisableProjectBuild> + </PropertyGroup> + <!-- Default configurations to help VS understand the configurations --> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> + </PropertyGroup> + <ItemGroup> + <Compile Include="Program.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\NetServer\NetServer.csproj" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Interop/COM/Activator/Program.cs b/tests/src/Interop/COM/Activator/Program.cs new file mode 100644 index 0000000000..117d55fa70 --- /dev/null +++ b/tests/src/Interop/COM/Activator/Program.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Activator +{ + using System; + using System.Runtime.InteropServices; + + using CoreFXTestLibrary; + + using Console = Internal.Console; + + class Program + { + static void InvalidInterfaceRequest() + { + Assert.Throws<NotSupportedException>( + () => + { + var notIClassFactory = new Guid("ED53F949-63E4-43B5-A13D-5655478AADD5"); + var cxt = new ComActivationContext() + { + InterfaceId = notIClassFactory + }; + ComActivator.GetClassFactoryForType(cxt); + }, + "Non-IClassFactory request should fail"); + } + + static void ClassNotRegistered() + { + COMException e = Assert.Throws<COMException>( + () => + { + var CLSID_NotRegistered = new Guid("328FF83E-3F6C-4BE9-A742-752562032925"); // Random GUID + var IID_IClassFactory = new Guid("00000001-0000-0000-C000-000000000046"); + var cxt = new ComActivationContext() + { + ClassId = CLSID_NotRegistered, + InterfaceId = IID_IClassFactory + }; + ComActivator.GetClassFactoryForType(cxt); + }, + "Class should not be found"); + + const int CLASS_E_CLASSNOTAVAILABLE = unchecked((int)0x80040111); + Assert.AreEqual(CLASS_E_CLASSNOTAVAILABLE, e.HResult, "Unexpected HRESULT"); + } + + static int Main(string[] doNotUse) + { + try + { + InvalidInterfaceRequest(); + ClassNotRegistered(); + } + catch (Exception e) + { + Console.WriteLine($"Test Failure: {e}"); + return 101; + } + + return 100; + } + } +} diff --git a/tests/src/Interop/COM/NETServer/ArrayTesting.cs b/tests/src/Interop/COM/NETServer/ArrayTesting.cs new file mode 100644 index 0000000000..3cdd5d100b --- /dev/null +++ b/tests/src/Interop/COM/NETServer/ArrayTesting.cs @@ -0,0 +1,241 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +#pragma warning disable 618 // Must test deprecated features + +[ComVisible(true)] +[Guid(Server.Contract.Guids.ArrayTesting)] +public class ArrayTesting : Server.Contract.IArrayTesting +{ + private static double Mean(byte[] d) + { + double t = 0.0; + foreach (var b in d) + { + t += b; + } + return (t / d.Length); + } + private static double Mean(short[] d) + { + double t = 0.0; + foreach (var b in d) + { + t += b; + } + return (t / d.Length); + } + private static double Mean(ushort[] d) + { + double t = 0.0; + foreach (var b in d) + { + t += b; + } + return (t / d.Length); + } + private static double Mean(int[] d) + { + double t = 0.0; + foreach (var b in d) + { + t += b; + } + return (t / d.Length); + } + private static double Mean(uint[] d) + { + double t = 0.0; + foreach (var b in d) + { + t += b; + } + return (t / d.Length); + } + private static double Mean(long[] d) + { + double t = 0.0; + foreach (var b in d) + { + t += b; + } + return (t / d.Length); + } + private static double Mean(ulong[] d) + { + double t = 0.0; + foreach (var b in d) + { + t += b; + } + return (t / d.Length); + } + private static double Mean(float[] d) + { + double t = 0.0; + foreach (var b in d) + { + t += b; + } + return (t / d.Length); + } + private static double Mean(double[] d) + { + double t = 0.0; + foreach (var b in d) + { + t += b; + } + return (t / d.Length); + } + + public double Mean_Byte_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] byte[] d) + { + return Mean(d); + } + + public double Mean_Short_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] short[] d) + { + return Mean(d); + } + + public double Mean_UShort_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] ushort[] d) + { + return Mean(d); + } + + public double Mean_Int_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] int[] d) + { + return Mean(d); + } + + public double Mean_UInt_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] uint[] d) + { + return Mean(d); + } + + public double Mean_Long_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] long[] d) + { + return Mean(d); + } + + public double Mean_ULong_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] ulong[] d) + { + return Mean(d); + } + + public double Mean_Float_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] float[] d) + { + return Mean(d); + } + + public double Mean_Double_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] double[] d) + { + return Mean(d); + } + + public double Mean_Byte_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] byte[] d, int len) + { + return Mean(d); + } + + public double Mean_Short_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] short[] d, int len) + { + return Mean(d); + } + + public double Mean_UShort_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] ushort[] d, int len) + { + return Mean(d); + } + + public double Mean_Int_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] int[] d, int len) + { + return Mean(d); + } + + public double Mean_UInt_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] uint[] d, int len) + { + return Mean(d); + } + + public double Mean_Long_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] long[] d, int len) + { + return Mean(d); + } + + public double Mean_ULong_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] ulong[] d, int len) + { + return Mean(d); + } + + public double Mean_Float_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] float[] d, int len) + { + return Mean(d); + } + + public double Mean_Double_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] double[] d, int len) + { + return Mean(d); + } + + public double Mean_Byte_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] byte[] d, out int len) + { + len = d.Length; + return Mean(d); + } + + public double Mean_Short_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] short[] d, out int len) + { + len = d.Length; + return Mean(d); + } + + public double Mean_UShort_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] ushort[] d, out int len) + { + len = d.Length; + return Mean(d); + } + + public double Mean_Int_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] int[] d, out int len) + { + len = d.Length; + return Mean(d); + } + + public double Mean_UInt_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] uint[] d, out int len) + { + len = d.Length; + return Mean(d); + } + + public double Mean_Long_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] long[] d, out int len) + { + len = d.Length; + return Mean(d); + } + + public double Mean_ULong_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] ulong[] d, out int len) + { + len = d.Length; + return Mean(d); + } + + public double Mean_Float_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] float[] d, out int len) + { + len = d.Length; + return Mean(d); + } + + public double Mean_Double_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] double[] d, out int len) + { + len = d.Length; + return Mean(d); + } +} + +#pragma warning restore 618 // Must test deprecated features
\ No newline at end of file diff --git a/tests/src/Interop/COM/NETServer/ErrorMarshalTesting.cs b/tests/src/Interop/COM/NETServer/ErrorMarshalTesting.cs new file mode 100644 index 0000000000..6bd104f5d4 --- /dev/null +++ b/tests/src/Interop/COM/NETServer/ErrorMarshalTesting.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +[ComVisible(true)] +[Guid(Server.Contract.Guids.ErrorMarshalTesting)] +public class ErrorMarshalTesting : Server.Contract.IErrorMarshalTesting +{ + public void Throw_HResult(int hresultToReturn) + { + // This GetExceptionForHR call is needed to 'eat' the IErrorInfo put to TLS by + // any previous exception on this thread. If this isn't done, calls can return + // previous exception objects that have occurred. + Marshal.GetExceptionForHR(hresultToReturn); + + Exception e = Marshal.GetExceptionForHR(hresultToReturn); + throw e; + } + + [PreserveSig] + public int Return_As_HResult(int hresultToReturn) + { + return hresultToReturn; + } +}
\ No newline at end of file diff --git a/tests/src/Interop/COM/NETServer/NETServer.csproj b/tests/src/Interop/COM/NETServer/NETServer.csproj index 214bb25c5a..0610fca6ae 100644 --- a/tests/src/Interop/COM/NETServer/NETServer.csproj +++ b/tests/src/Interop/COM/NETServer/NETServer.csproj @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Interop.settings.targets))\Interop.settings.targets" /> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> @@ -9,8 +10,6 @@ <ProjectGuid>{C04AB564-CC61-499D-9F4C-AA1A9FDE42C9}</ProjectGuid> <OutputType>library</OutputType> <ProjectTypeGuids>{4948E98A-ECFC-4988-851E-68E1ADD2DD5A};{B850CC46-E8FB-4569-A28D-423F81E8A861}</ProjectTypeGuids> - <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> - <DefineConstants>$(DefineConstants);STATIC</DefineConstants> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> @@ -18,16 +17,13 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> </PropertyGroup> <ItemGroup> - <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> - <Visible>False</Visible> - </CodeAnalysisDependentAssemblyPaths> - </ItemGroup> - <ItemGroup> <Compile Include="ImportedTypes.cs" /> + <Compile Include="NumericTesting.cs" /> + <Compile Include="ArrayTesting.cs" /> + <Compile Include="StringTesting.cs" /> + <Compile Include="ErrorMarshalTesting.cs" /> + <Compile Include="../ServerContracts/Primitives.cs" /> <Compile Include="../ServerContracts/ServerGuids.cs" /> </ItemGroup> - <ItemGroup> - <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/tests/src/Interop/COM/NETServer/NumericTesting.cs b/tests/src/Interop/COM/NETServer/NumericTesting.cs new file mode 100644 index 0000000000..c6b11630ef --- /dev/null +++ b/tests/src/Interop/COM/NETServer/NumericTesting.cs @@ -0,0 +1,193 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +#pragma warning disable 618 // Must test deprecated features + +[ComVisible(true)] +[Guid(Server.Contract.Guids.NumericTesting)] +public class NumericTesting : Server.Contract.INumericTesting +{ + public byte Add_Byte(byte a, byte b) + { + return (byte)(a + b); + } + + public short Add_Short(short a, short b) + { + return (short)(a + b); + } + + public ushort Add_UShort(ushort a, ushort b) + { + return (ushort)(a + b); + } + + public int Add_Int(int a, int b) + { + return a + b; + } + + public uint Add_UInt(uint a, uint b) + { + return a + b; + } + + public long Add_Long(long a, long b) + { + return a + b; + } + + public ulong Add_ULong(ulong a, ulong b) + { + return a + b; + } + + public float Add_Float(float a, float b) + { + return a + b; + } + + public double Add_Double(double a, double b) + { + return a + b; + } + + public void Add_Byte_Ref(byte a, byte b, ref byte c) + { + if (c != byte.MaxValue) + { + throw new Exception(); + } + + c = (byte)(a + b); + } + + public void Add_Short_Ref(short a, short b, ref short c) + { + if (c != short.MaxValue) + { + throw new Exception(); + } + + c = (short)(a + b); + } + + public void Add_UShort_Ref(ushort a, ushort b, ref ushort c) + { + if (c != ushort.MaxValue) + { + throw new Exception(); + } + + c = (ushort)(a + b); + } + + public void Add_Int_Ref(int a, int b, ref int c) + { + if (c != int.MaxValue) + { + throw new Exception(); + } + + c = a + b; + } + + public void Add_UInt_Ref(uint a, uint b, ref uint c) + { + if (c != uint.MaxValue) + { + throw new Exception(); + } + + c = a + b; + } + + public void Add_Long_Ref(long a, long b, ref long c) + { + if (c != long.MaxValue) + { + throw new Exception(); + } + + c = a + b; + } + + public void Add_ULong_Ref(ulong a, ulong b, ref ulong c) + { + if (c != ulong.MaxValue) + { + throw new Exception(); + } + + c = a + b; + } + + public void Add_Float_Ref(float a, float b, ref float c) + { + if (c != float.MaxValue) + { + throw new Exception(); + } + + c = a + b; + } + + public void Add_Double_Ref(double a, double b, ref double c) + { + if (c != double.MaxValue) + { + throw new Exception(); + } + + c = a + b; + } + + public void Add_Byte_Out(byte a, byte b, out byte c) + { + c = (byte)(a + b); + } + + public void Add_Short_Out(short a, short b, out short c) + { + c = (short)(a + b); + } + + public void Add_UShort_Out(ushort a, ushort b, out ushort c) + { + c = (ushort)(a + b); + } + + public void Add_Int_Out(int a, int b, out int c) + { + c = a + b; + } + + public void Add_UInt_Out(uint a, uint b, out uint c) + { + c = a + b; + } + + public void Add_Long_Out(long a, long b, out long c) + { + c = a + b; + } + + public void Add_ULong_Out(ulong a, ulong b, out ulong c) + { + c = a + b; + } + + public void Add_Float_Out(float a, float b, out float c) + { + c = a + b; + } + + public void Add_Double_Out(double a, double b, out double c) + { + c = a + b; + } +}
\ No newline at end of file diff --git a/tests/src/Interop/COM/NETServer/StringTesting.cs b/tests/src/Interop/COM/NETServer/StringTesting.cs new file mode 100644 index 0000000000..3a510f5e9b --- /dev/null +++ b/tests/src/Interop/COM/NETServer/StringTesting.cs @@ -0,0 +1,191 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text; +using System.Runtime.InteropServices; + +#pragma warning disable 618 // Must test deprecated features + +[ComVisible(true)] +[Guid(Server.Contract.Guids.StringTesting)] +public class StringTesting : Server.Contract.IStringTesting +{ + private static string Reverse(string s) + { + var chars = s.ToCharArray(); + Array.Reverse(chars); + return new string(chars); + } + + [return: MarshalAs(UnmanagedType.LPStr)] + public string Add_LPStr( + [MarshalAs(UnmanagedType.LPStr)] string a, + [MarshalAs(UnmanagedType.LPStr)] string b) + { + return a + b; + } + + [return: MarshalAs(UnmanagedType.LPWStr)] + public string Add_LPWStr( + [MarshalAs(UnmanagedType.LPWStr)] string a, + [MarshalAs(UnmanagedType.LPWStr)] string b) + { + return a + b; + } + + [return: MarshalAs(UnmanagedType.BStr)] + public string Add_BStr( + [MarshalAs(UnmanagedType.BStr)] string a, + [MarshalAs(UnmanagedType.BStr)] string b) + { + return a + b; + } + + // LPStr + + [return: MarshalAs(UnmanagedType.LPStr)] + public string Reverse_LPStr([MarshalAs(UnmanagedType.LPStr)] string a) + { + return Reverse(a); + } + + [return: MarshalAs(UnmanagedType.LPStr)] + public string Reverse_LPStr_Ref([MarshalAs(UnmanagedType.LPStr)] ref string a) + { + return Reverse(a); + } + + [return: MarshalAs(UnmanagedType.LPStr)] + public string Reverse_LPStr_InRef([In][MarshalAs(UnmanagedType.LPStr)] ref string a) + { + return Reverse(a); + } + + public void Reverse_LPStr_Out([MarshalAs(UnmanagedType.LPStr)] string a, [MarshalAs(UnmanagedType.LPStr)] out string b) + { + b = Reverse(a); + } + + public void Reverse_LPStr_OutAttr([MarshalAs(UnmanagedType.LPStr)] string a, [Out][MarshalAs(UnmanagedType.LPStr)] string b) + { + b = Reverse(a); + } + + [return: MarshalAs(UnmanagedType.LPStr)] + public StringBuilder Reverse_SB_LPStr([MarshalAs(UnmanagedType.LPStr)] StringBuilder a) + { + return new StringBuilder(Reverse(a.ToString())); + } + + [return: MarshalAs(UnmanagedType.LPStr)] + public StringBuilder Reverse_SB_LPStr_Ref([MarshalAs(UnmanagedType.LPStr)] ref StringBuilder a) + { + return new StringBuilder(Reverse(a.ToString())); + } + + [return: MarshalAs(UnmanagedType.LPStr)] + public StringBuilder Reverse_SB_LPStr_InRef([In][MarshalAs(UnmanagedType.LPStr)] ref StringBuilder a) + { + return new StringBuilder(Reverse(a.ToString())); + } + + public void Reverse_SB_LPStr_Out([MarshalAs(UnmanagedType.LPStr)] StringBuilder a, [MarshalAs(UnmanagedType.LPStr)] out StringBuilder b) + { + b = new StringBuilder(Reverse(a.ToString())); + } + + public void Reverse_SB_LPStr_OutAttr([MarshalAs(UnmanagedType.LPStr)] StringBuilder a, [Out][MarshalAs(UnmanagedType.LPStr)] StringBuilder b) + { + b.Append(Reverse(a.ToString())); + } + + // LPWStr + + [return: MarshalAs(UnmanagedType.LPWStr)] + public string Reverse_LPWStr([MarshalAs(UnmanagedType.LPWStr)] string a) + { + return Reverse(a); + } + + [return: MarshalAs(UnmanagedType.LPWStr)] + public string Reverse_LPWStr_Ref([MarshalAs(UnmanagedType.LPWStr)] ref string a) + { + return Reverse(a); + } + + [return: MarshalAs(UnmanagedType.LPWStr)] + public string Reverse_LPWStr_InRef([In][MarshalAs(UnmanagedType.LPWStr)] ref string a) + { + return Reverse(a); + } + + public void Reverse_LPWStr_Out([MarshalAs(UnmanagedType.LPWStr)] string a, [MarshalAs(UnmanagedType.LPWStr)] out string b) + { + b = Reverse(a); + } + + public void Reverse_LPWStr_OutAttr([MarshalAs(UnmanagedType.LPWStr)] string a, [Out][MarshalAs(UnmanagedType.LPWStr)] string b) + { + b = Reverse(a); + } + + [return: MarshalAs(UnmanagedType.LPWStr)] + public StringBuilder Reverse_SB_LPWStr([MarshalAs(UnmanagedType.LPWStr)] StringBuilder a) + { + return new StringBuilder(Reverse(a.ToString())); + } + + [return: MarshalAs(UnmanagedType.LPWStr)] + public StringBuilder Reverse_SB_LPWStr_Ref([MarshalAs(UnmanagedType.LPWStr)] ref StringBuilder a) + { + return new StringBuilder(Reverse(a.ToString())); + } + + [return: MarshalAs(UnmanagedType.LPWStr)] + public StringBuilder Reverse_SB_LPWStr_InRef([In][MarshalAs(UnmanagedType.LPWStr)] ref StringBuilder a) + { + return new StringBuilder(Reverse(a.ToString())); + } + + public void Reverse_SB_LPWStr_Out([MarshalAs(UnmanagedType.LPWStr)] StringBuilder a, [MarshalAs(UnmanagedType.LPWStr)] out StringBuilder b) + { + b = new StringBuilder(Reverse(a.ToString())); + } + + public void Reverse_SB_LPWStr_OutAttr([MarshalAs(UnmanagedType.LPWStr)] StringBuilder a, [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder b) + { + b.Append(Reverse(a.ToString())); + } + + // BSTR + + [return: MarshalAs(UnmanagedType.BStr)] + public string Reverse_BStr([MarshalAs(UnmanagedType.BStr)] string a) + { + return Reverse(a); + } + + [return: MarshalAs(UnmanagedType.BStr)] + public string Reverse_BStr_Ref([MarshalAs(UnmanagedType.BStr)] ref string a) + { + return Reverse(a); + } + + [return: MarshalAs(UnmanagedType.BStr)] + public string Reverse_BStr_InRef([In][MarshalAs(UnmanagedType.BStr)] ref string a) + { + return Reverse(a); + } + + public void Reverse_BStr_Out([MarshalAs(UnmanagedType.BStr)] string a, [MarshalAs(UnmanagedType.BStr)] out string b) + { + b = Reverse(a); + } + + public void Reverse_BStr_OutAttr([MarshalAs(UnmanagedType.BStr)] string a, [Out][MarshalAs(UnmanagedType.BStr)] string b) + { + b = Reverse(a); + } +}
\ No newline at end of file diff --git a/tests/src/Interop/COM/NativeClients/Primitives.csproj b/tests/src/Interop/COM/NativeClients/Primitives.csproj new file mode 100644 index 0000000000..b1bc0e656c --- /dev/null +++ b/tests/src/Interop/COM/NativeClients/Primitives.csproj @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Interop.settings.targets))\Interop.settings.targets" /> + <PropertyGroup> + <IgnoreInteropAssertionFile>true</IgnoreInteropAssertionFile> + <CLRTestScriptLocalCoreShim>true</CLRTestScriptLocalCoreShim> + </PropertyGroup> + <ItemGroup> + <Compile Include="$(InteropCommonDir)ExeLauncherProgram.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="Primitives/CMakeLists.txt"/> + <ProjectReference Include="../NetServer/NetServer.csproj" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project>
\ No newline at end of file diff --git a/tests/src/Interop/COM/NativeClients/Primitives/App.manifest b/tests/src/Interop/COM/NativeClients/Primitives/App.manifest new file mode 100644 index 0000000000..ed665080a7 --- /dev/null +++ b/tests/src/Interop/COM/NativeClients/Primitives/App.manifest @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity + type="win32" + name="COMClientPrimitives" + version="1.0.0.0"/> + + <dependency> + <dependentAssembly> + <!-- RegFree COM - CoreCLR Shim --> + <assemblyIdentity + type="win32" + name="CoreShim.X" + version="1.0.0.0"/> + </dependentAssembly> + </dependency> +</assembly>
\ No newline at end of file diff --git a/tests/src/Interop/COM/NativeClients/Primitives/ArrayTests.cpp b/tests/src/Interop/COM/NativeClients/Primitives/ArrayTests.cpp new file mode 100644 index 0000000000..5b54a1445b --- /dev/null +++ b/tests/src/Interop/COM/NativeClients/Primitives/ArrayTests.cpp @@ -0,0 +1,318 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include "ClientTests.h" +#include <numeric> +#include <vector> + +namespace +{ + bool EqualByBound(double expected, double actual) + { + double low = expected - 0.00001; + double high = expected + 0.00001; + double eps = std::fabs(expected - actual); + bool isEqual = eps < std::numeric_limits<double>::epsilon() || (low < actual && actual < high); + return isEqual; + } + + template<typename T> + std::vector<T> Convert(_In_ const std::vector<int> &in) + { + std::vector<T> out; + for (auto i : in) + out.push_back((T)i); + return out; + } + + template<typename T> + VARTYPE ToSafeArrayType(); + template<> + VARTYPE ToSafeArrayType<byte>() { return VT_UI1; } + template<> + VARTYPE ToSafeArrayType<int16_t>() { return VT_I2; } + template<> + VARTYPE ToSafeArrayType<uint16_t>() { return VT_UI2; } + template<> + VARTYPE ToSafeArrayType<int32_t>() { return VT_I4; } + template<> + VARTYPE ToSafeArrayType<uint32_t>() { return VT_UI4; } + template<> + VARTYPE ToSafeArrayType<int64_t>() { return VT_I8; } + template<> + VARTYPE ToSafeArrayType<uint64_t>() { return VT_UI8; } + template<> + VARTYPE ToSafeArrayType<float>() { return VT_R4; } + template<> + VARTYPE ToSafeArrayType<double>() { return VT_R8; } + + template<typename T> + class SafeArraySmartPtr + { + public: + SafeArraySmartPtr(_In_ const std::vector<T> &in) + : _safeArray{} + , _elementCount{ static_cast<int>(in.size()) } + { + SAFEARRAYBOUND saBound; + saBound.lLbound = 0; + saBound.cElements = static_cast<ULONG>(in.size()); + + _safeArray = ::SafeArrayCreate(ToSafeArrayType<T>(), 1, &saBound); + assert(_safeArray != nullptr); + + std::memcpy(static_cast<T*>(_safeArray->pvData), in.data(), sizeof(T) * in.size()); + } + + ~SafeArraySmartPtr() + { + ::SafeArrayDestroy(_safeArray); + } + + int Length() const + { + return _elementCount; + } + + operator SAFEARRAY *() + { + return _safeArray; + } + + private: + int _elementCount; + SAFEARRAY *_safeArray; + }; + + void ByteArray(_In_ IArrayTesting *arrayTesting, _In_ const std::vector<int> &baseData, _In_ double expectedMean) + { + HRESULT hr; + auto data = Convert<byte>(baseData); + + ::printf("Byte[] marshalling\n"); + + double actual; + THROW_IF_FAILED(arrayTesting->raw_Mean_Byte_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + THROW_IF_FAILED(arrayTesting->raw_Mean_Byte_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + int len; + SafeArraySmartPtr<byte> saData{ data }; + THROW_IF_FAILED(arrayTesting->raw_Mean_Byte_SafeArray_OutLen(saData, &len, &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + THROW_FAIL_IF_FALSE(len == saData.Length()); + } + + void ShortArray(_In_ IArrayTesting *arrayTesting, _In_ const std::vector<int> &baseData, _In_ double expectedMean) + { + HRESULT hr; + auto data = Convert<int16_t>(baseData); + + ::printf("Short[] marshalling\n"); + + double actual; + THROW_IF_FAILED(arrayTesting->raw_Mean_Short_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + THROW_IF_FAILED(arrayTesting->raw_Mean_Short_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + int len; + SafeArraySmartPtr<int16_t> saData{ data }; + THROW_IF_FAILED(arrayTesting->raw_Mean_Short_SafeArray_OutLen(saData, &len, &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + THROW_FAIL_IF_FALSE(len == saData.Length()); + } + + void UShortArray(_In_ IArrayTesting *arrayTesting, _In_ const std::vector<int> &baseData, _In_ double expectedMean) + { + HRESULT hr; + auto data = Convert<uint16_t>(baseData); + + ::printf("UShort[] marshalling\n"); + + double actual; + THROW_IF_FAILED(arrayTesting->raw_Mean_UShort_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + THROW_IF_FAILED(arrayTesting->raw_Mean_UShort_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + int len; + SafeArraySmartPtr<uint16_t> saData{ data }; + THROW_IF_FAILED(arrayTesting->raw_Mean_UShort_SafeArray_OutLen(saData, &len, &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + THROW_FAIL_IF_FALSE(len == saData.Length()); + } + + void IntArray(_In_ IArrayTesting *arrayTesting, _In_ const std::vector<int> &baseData, _In_ double expectedMean) + { + HRESULT hr; + auto data = Convert<int32_t>(baseData); + + ::printf("Int[] marshalling\n"); + + double actual; + THROW_IF_FAILED(arrayTesting->raw_Mean_Int_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + THROW_IF_FAILED(arrayTesting->raw_Mean_Int_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + int len; + SafeArraySmartPtr<int32_t> saData{ data }; + THROW_IF_FAILED(arrayTesting->raw_Mean_Int_SafeArray_OutLen(saData, &len, &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + THROW_FAIL_IF_FALSE(len == saData.Length()); + } + + void UIntArray(_In_ IArrayTesting *arrayTesting, _In_ const std::vector<int> &baseData, _In_ double expectedMean) + { + HRESULT hr; + auto data = Convert<uint32_t>(baseData); + + ::printf("UInt[] marshalling\n"); + + double actual; + THROW_IF_FAILED(arrayTesting->raw_Mean_UInt_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + THROW_IF_FAILED(arrayTesting->raw_Mean_UInt_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + int len; + SafeArraySmartPtr<uint32_t> saData{ data }; + THROW_IF_FAILED(arrayTesting->raw_Mean_UInt_SafeArray_OutLen(saData, &len, &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + THROW_FAIL_IF_FALSE(len == saData.Length()); + } + + void LongArray(_In_ IArrayTesting *arrayTesting, _In_ const std::vector<int> &baseData, _In_ double expectedMean) + { + HRESULT hr; + auto data = Convert<int64_t>(baseData); + + ::printf("Long[] marshalling\n"); + + double actual; + THROW_IF_FAILED(arrayTesting->raw_Mean_Long_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + THROW_IF_FAILED(arrayTesting->raw_Mean_Long_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + int len; + SafeArraySmartPtr<int64_t> saData{ data }; + THROW_IF_FAILED(arrayTesting->raw_Mean_Long_SafeArray_OutLen(saData, &len, &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + THROW_FAIL_IF_FALSE(len == saData.Length()); + } + + void ULongArray(_In_ IArrayTesting *arrayTesting, _In_ const std::vector<int> &baseData, _In_ double expectedMean) + { + HRESULT hr; + auto data = Convert<uint64_t>(baseData); + + ::printf("ULong[] marshalling\n"); + + double actual; + THROW_IF_FAILED(arrayTesting->raw_Mean_ULong_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + THROW_IF_FAILED(arrayTesting->raw_Mean_ULong_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + int len; + SafeArraySmartPtr<uint64_t> saData{ data }; + THROW_IF_FAILED(arrayTesting->raw_Mean_ULong_SafeArray_OutLen(saData, &len, &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + THROW_FAIL_IF_FALSE(len == saData.Length()); + } + + void FloatArray(_In_ IArrayTesting *arrayTesting, _In_ const std::vector<int> &baseData, _In_ double expectedMean) + { + HRESULT hr; + auto data = Convert<float>(baseData); + + ::printf("Float[] marshalling\n"); + + double actual; + THROW_IF_FAILED(arrayTesting->raw_Mean_Float_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + THROW_IF_FAILED(arrayTesting->raw_Mean_Float_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + int len; + SafeArraySmartPtr<float> saData{ data }; + THROW_IF_FAILED(arrayTesting->raw_Mean_Float_SafeArray_OutLen(saData, &len, &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + THROW_FAIL_IF_FALSE(len == saData.Length()); + } + + void DoubleArray(_In_ IArrayTesting *arrayTesting, _In_ const std::vector<int> &baseData, _In_ double expectedMean) + { + HRESULT hr; + auto data = Convert<double>(baseData); + + ::printf("Double[] marshalling\n"); + + double actual; + THROW_IF_FAILED(arrayTesting->raw_Mean_Double_LP_PreLen(static_cast<int>(baseData.size()), data.data(), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + THROW_IF_FAILED(arrayTesting->raw_Mean_Double_LP_PostLen(data.data(), static_cast<int>(baseData.size()), &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + + actual = 0.0; + int len; + SafeArraySmartPtr<double> saData{ data }; + THROW_IF_FAILED(arrayTesting->raw_Mean_Double_SafeArray_OutLen(saData, &len, &actual)); + THROW_FAIL_IF_FALSE(EqualByBound(expectedMean, actual)); + THROW_FAIL_IF_FALSE(len == saData.Length()); + } +} + +void Run_ArrayTests() +{ + HRESULT hr; + + CoreShimComActivation csact{ W("NETServer.dll"), W("ArrayTesting") }; + + ComSmartPtr<IArrayTesting> arrayTesting; + THROW_IF_FAILED(::CoCreateInstance(CLSID_ArrayTesting, nullptr, CLSCTX_INPROC, IID_IArrayTesting, (void**)&arrayTesting)); + + std::vector<int> baseData(10); + std::iota(std::begin(baseData), std::end(baseData), 0); + double mean = std::accumulate(std::begin(baseData), std::end(baseData), 0.0) / baseData.size(); + + ByteArray(arrayTesting, baseData, mean); + ShortArray(arrayTesting, baseData, mean); + UShortArray(arrayTesting, baseData, mean); + IntArray(arrayTesting, baseData, mean); + UIntArray(arrayTesting, baseData, mean); + LongArray(arrayTesting, baseData, mean); + ULongArray(arrayTesting, baseData, mean); + FloatArray(arrayTesting, baseData, mean); + DoubleArray(arrayTesting, baseData, mean); +} diff --git a/tests/src/Interop/COM/NativeClients/Primitives/CMakeLists.txt b/tests/src/Interop/COM/NativeClients/Primitives/CMakeLists.txt new file mode 100644 index 0000000000..b2b2fb00db --- /dev/null +++ b/tests/src/Interop/COM/NativeClients/Primitives/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required (VERSION 2.6) + +project (COMClientPrimitives) +include_directories( ${INC_PLATFORM_DIR} ) +include_directories( "../../ServerContracts" ) +include_directories( "../../NativeServer" ) +set(SOURCES + Client.cpp + NumericTests.cpp + ArrayTests.cpp + StringTests.cpp + ErrorTests.cpp + App.manifest) + +# add the executable +add_executable (COMClientPrimitives ${SOURCES}) +target_link_libraries(COMClientPrimitives ${LINK_LIBRARIES_ADDITIONAL}) + +# Copy CoreShim manifest to project output +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/CoreShim.X.manifest INPUT ${CMAKE_CURRENT_SOURCE_DIR}/CoreShim.X.manifest) + +# add the install targets +install (TARGETS COMClientPrimitives DESTINATION bin) diff --git a/tests/src/Interop/COM/NativeClients/Primitives/Client.cpp b/tests/src/Interop/COM/NativeClients/Primitives/Client.cpp new file mode 100644 index 0000000000..bfb32c5b9a --- /dev/null +++ b/tests/src/Interop/COM/NativeClients/Primitives/Client.cpp @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include "ClientTests.h" + +template<COINIT TM> +struct ComInit +{ + const HRESULT Result; + + ComInit() + : Result{ ::CoInitializeEx(nullptr, TM) } + { } + + ~ComInit() + { + if (SUCCEEDED(Result)) + ::CoUninitialize(); + } +}; + +using ComMTA = ComInit<COINIT_MULTITHREADED>; + +int __cdecl main() +{ + ComMTA init; + if (FAILED(init.Result)) + return -1; + + try + { + Run_NumericTests(); + Run_ArrayTests(); + Run_StringTests(); + Run_ErrorTests(); + } + catch (HRESULT hr) + { + ::printf("Test Failure: 0x%08x\n", hr); + return 101; + } + + return 100; +} diff --git a/tests/src/Interop/COM/NativeClients/Primitives/ClientTests.h b/tests/src/Interop/COM/NativeClients/Primitives/ClientTests.h new file mode 100644 index 0000000000..029ed028ce --- /dev/null +++ b/tests/src/Interop/COM/NativeClients/Primitives/ClientTests.h @@ -0,0 +1,70 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include <xplatform.h> +#include <cassert> +#include <Server.Contracts.tlh> + +#define COM_CLIENT +#include <Servers.h> + +#define THROW_IF_FAILED(exp) { hr = exp; if (FAILED(hr)) { ::printf("FAILURE: 0x%08x = %s\n", hr, #exp); throw hr; } } +#define THROW_FAIL_IF_FALSE(exp) { if (!(exp)) { ::printf("FALSE: %s\n", #exp); throw E_FAIL; } } + +template<typename T> +struct ComSmartPtr +{ + ComSmartPtr() + : p{} + { } + + ComSmartPtr(_In_ const ComSmartPtr &) = delete; + ComSmartPtr(_Inout_ ComSmartPtr &&) = delete; + + ComSmartPtr& operator=(_In_ const ComSmartPtr &) = delete; + ComSmartPtr& operator=(_Inout_ ComSmartPtr &&) = delete; + + ~ComSmartPtr() + { + if (p != nullptr) + p->Release(); + } + + operator T*() + { + return p; + } + + T** operator&() + { + return &p; + } + + T* operator->() + { + return p; + } + + void Attach(_In_opt_ T *t) + { + if (p != nullptr) + p->Release(); + + p = t; + } + + T *Detach() + { + T *tmp = p; + p = nullptr; + return tmp; + } + + T *p; +}; + +void Run_NumericTests(); +void Run_ArrayTests(); +void Run_StringTests(); +void Run_ErrorTests(); diff --git a/tests/src/Interop/COM/NativeClients/Primitives/CoreShim.X.manifest b/tests/src/Interop/COM/NativeClients/Primitives/CoreShim.X.manifest new file mode 100644 index 0000000000..1dba8e03b3 --- /dev/null +++ b/tests/src/Interop/COM/NativeClients/Primitives/CoreShim.X.manifest @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + +<assemblyIdentity + type="win32" + name="CoreShim.X" + version="1.0.0.0" /> + +<file name="CoreShim.dll"> + <!-- NumericTesting --> + <comClass + clsid="{53169A33-E85D-4E3C-B668-24E438D0929B}" + threadingModel="Both" /> + <!-- ArrayTesting --> + <comClass + clsid="{B99ABE6A-DFF6-440F-BFB6-55179B8FE18E}" + threadingModel="Both" /> + <!-- StringTesting --> + <comClass + clsid="{C73C83E8-51A2-47F8-9B5C-4284458E47A6}" + threadingModel="Both" /> + <!-- ErrorMarshalTesting --> + <comClass + clsid="{71CF5C45-106C-4B32-B418-43A463C6041F}" + threadingModel="Both" /> +</file> + +</assembly> diff --git a/tests/src/Interop/COM/NativeClients/Primitives/ErrorTests.cpp b/tests/src/Interop/COM/NativeClients/Primitives/ErrorTests.cpp new file mode 100644 index 0000000000..9f0af224bd --- /dev/null +++ b/tests/src/Interop/COM/NativeClients/Primitives/ErrorTests.cpp @@ -0,0 +1,68 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include "ClientTests.h" + +namespace +{ + void VerifyExpectedException(_In_ IErrorMarshalTesting *et) + { + ::printf("Verify expected exception from HRESULT\n"); + + HRESULT hrs[] = + { + E_NOTIMPL, + E_POINTER, + E_ACCESSDENIED, + E_OUTOFMEMORY, + E_INVALIDARG, + E_UNEXPECTED, + HRESULT{-1} + }; + + for (int i = 0; i < ARRAYSIZE(hrs); ++i) + { + HRESULT hr = hrs[i]; + HRESULT hrMaybe = et->raw_Throw_HResult(hr); + THROW_FAIL_IF_FALSE(hr == hrMaybe); + } + } + + void VerifyReturnHResult(_In_ IErrorMarshalTesting *et) + { + ::printf("Verify preserved function signature\n"); + + HRESULT hrs[] = + { + E_NOTIMPL, + E_POINTER, + E_ACCESSDENIED, + E_INVALIDARG, + E_UNEXPECTED, + HRESULT{-1}, + S_FALSE, + HRESULT{2} + }; + + for (int i = 0; i < ARRAYSIZE(hrs); ++i) + { + HRESULT hr = hrs[i]; + HRESULT hrMaybe = et->Return_As_HResult(hr); + THROW_FAIL_IF_FALSE(hr == hrMaybe); + } + } +} + +void Run_ErrorTests() +{ + HRESULT hr; + + CoreShimComActivation csact{ W("NETServer.dll"), W("ErrorMarshalTesting") }; + + ComSmartPtr<IErrorMarshalTesting> errorMarshal; + THROW_IF_FAILED(::CoCreateInstance(CLSID_ErrorMarshalTesting, nullptr, CLSCTX_INPROC, IID_IErrorMarshalTesting, (void**)&errorMarshal)); + + VerifyExpectedException(errorMarshal); + VerifyReturnHResult(errorMarshal); +} diff --git a/tests/src/Interop/COM/NativeClients/Primitives/NumericTests.cpp b/tests/src/Interop/COM/NativeClients/Primitives/NumericTests.cpp new file mode 100644 index 0000000000..68ae4f4560 --- /dev/null +++ b/tests/src/Interop/COM/NativeClients/Primitives/NumericTests.cpp @@ -0,0 +1,227 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include "ClientTests.h" +#include <cstdint> +#include <limits> + +namespace +{ + void MarshalByte(_In_ INumericTesting *numericTesting, _In_ byte a, _In_ byte b) + { + HRESULT hr; + + byte expected = a + b; + ::printf("Byte test invariant: %d + %d = %d\n", a, b, expected); + + byte c; + THROW_IF_FAILED(numericTesting->raw_Add_Byte(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = std::numeric_limits<decltype(c)>::max(); + THROW_IF_FAILED(numericTesting->raw_Add_Byte_Ref(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = 0; + THROW_IF_FAILED(numericTesting->raw_Add_Byte_Out(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + } + + void MarshalShort(_In_ INumericTesting *numericTesting, _In_ int16_t a, _In_ int16_t b) + { + HRESULT hr; + + int16_t expected = a + b; + ::printf("Short test invariant: %d + %d = %d\n", a, b, expected); + + int16_t c; + THROW_IF_FAILED(numericTesting->raw_Add_Short(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = std::numeric_limits<decltype(c)>::max(); + THROW_IF_FAILED(numericTesting->raw_Add_Short_Ref(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = 0; + THROW_IF_FAILED(numericTesting->raw_Add_Short_Out(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + } + + void MarshalUShort(_In_ INumericTesting *numericTesting, _In_ uint16_t a, _In_ uint16_t b) + { + HRESULT hr; + + uint16_t expected = a + b; + ::printf("UShort test invariant: %u + %u = %u\n", a, b, expected); + + uint16_t c; + THROW_IF_FAILED(numericTesting->raw_Add_UShort(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = std::numeric_limits<decltype(c)>::max(); + THROW_IF_FAILED(numericTesting->raw_Add_UShort_Ref(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = 0; + THROW_IF_FAILED(numericTesting->raw_Add_UShort_Out(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + } + + void MarshalInt(_In_ INumericTesting *numericTesting, _In_ int32_t a, _In_ int32_t b) + { + HRESULT hr; + + int32_t expected = a + b; + ::printf("Int test invariant: %d + %d = %d\n", a, b, expected); + + int32_t c; + THROW_IF_FAILED(numericTesting->raw_Add_Int(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = std::numeric_limits<decltype(c)>::max(); + THROW_IF_FAILED(numericTesting->raw_Add_Int_Ref(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = 0; + THROW_IF_FAILED(numericTesting->raw_Add_Int_Out(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + } + + void MarshalUInt(_In_ INumericTesting *numericTesting, _In_ uint32_t a, _In_ uint32_t b) + { + HRESULT hr; + + uint32_t expected = a + b; + ::printf("UInt test invariant: %u + %u = %u\n", a, b, expected); + + uint32_t c; + THROW_IF_FAILED(numericTesting->raw_Add_UInt(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = std::numeric_limits<decltype(c)>::max(); + THROW_IF_FAILED(numericTesting->raw_Add_UInt_Ref(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = 0; + THROW_IF_FAILED(numericTesting->raw_Add_UInt_Out(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + } + + void MarshalLong(_In_ INumericTesting *numericTesting, _In_ int64_t a, _In_ int64_t b) + { + HRESULT hr; + + int64_t expected = a + b; + ::printf("Long test invariant: %lld + %lld = %lld\n", a, b, expected); + + int64_t c; + THROW_IF_FAILED(numericTesting->raw_Add_Long(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = std::numeric_limits<decltype(c)>::max(); + THROW_IF_FAILED(numericTesting->raw_Add_Long_Ref(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = 0; + THROW_IF_FAILED(numericTesting->raw_Add_Long_Out(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + } + + void MarshalULong(_In_ INumericTesting *numericTesting, _In_ uint64_t a, _In_ uint64_t b) + { + HRESULT hr; + + uint64_t expected = a + b; + ::printf("ULong test invariant: %llu + %llu = %llu\n", a, b, expected); + + uint64_t c; + THROW_IF_FAILED(numericTesting->raw_Add_ULong(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = std::numeric_limits<decltype(c)>::max(); + THROW_IF_FAILED(numericTesting->raw_Add_ULong_Ref(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + + c = 0; + THROW_IF_FAILED(numericTesting->raw_Add_ULong_Out(a, b, &c)); + THROW_FAIL_IF_FALSE(expected == c); + } + + template<typename T> + bool EqualByBound(_In_ T expected, _In_ T actual) + { + T low = expected - (T)0.0001; + T high = expected + (T)0.0001; + T eps = std::abs(expected - actual); + return (eps < std::numeric_limits<T>::epsilon() || (low < actual && actual < high)); + } + + void MarshalFloat(_In_ INumericTesting *numericTesting, _In_ float a, _In_ float b) + { + HRESULT hr; + + float expected = a + b; + ::printf("Float test invariant: %f + %f = %f\n", a, b, expected); + + float c; + THROW_IF_FAILED(numericTesting->raw_Add_Float(a, b, &c)); + THROW_FAIL_IF_FALSE(EqualByBound(expected, c)); + + c = std::numeric_limits<decltype(c)>::max(); + THROW_IF_FAILED(numericTesting->raw_Add_Float_Ref(a, b, &c)); + THROW_FAIL_IF_FALSE(EqualByBound(expected, c)); + + c = 0; + THROW_IF_FAILED(numericTesting->raw_Add_Float_Out(a, b, &c)); + THROW_FAIL_IF_FALSE(EqualByBound(expected, c)); + } + + void MarshalDouble(_In_ INumericTesting *numericTesting, _In_ double a, _In_ double b) + { + HRESULT hr; + + double expected = a + b; + ::printf("Double test invariant: %f + %f = %f\n", a, b, expected); + + double c; + THROW_IF_FAILED(numericTesting->raw_Add_Double(a, b, &c)); + THROW_FAIL_IF_FALSE(EqualByBound(expected, c)); + + c = std::numeric_limits<decltype(c)>::max(); + THROW_IF_FAILED(numericTesting->raw_Add_Double_Ref(a, b, &c)); + THROW_FAIL_IF_FALSE(EqualByBound(expected, c)); + + c = 0; + THROW_IF_FAILED(numericTesting->raw_Add_Double_Out(a, b, &c)); + THROW_FAIL_IF_FALSE(EqualByBound(expected, c)); + } +} + +void Run_NumericTests() +{ + HRESULT hr; + + CoreShimComActivation csact{ W("NETServer.dll"), W("NumericTesting") }; + + ComSmartPtr<INumericTesting> numericTesting; + THROW_IF_FAILED(::CoCreateInstance(CLSID_NumericTesting, nullptr, CLSCTX_INPROC, IID_INumericTesting, (void**)&numericTesting)); + + int seed = 37; + ::srand(seed); + + ::printf("Numeric RNG seed: %d\n", seed); + + int a = ::rand(); + int b = ::rand(); + + MarshalByte(numericTesting, (byte)a, (byte)b); + MarshalShort(numericTesting, (int16_t)a, (int16_t)b); + MarshalUShort(numericTesting, (uint16_t)a, (uint16_t)b); + MarshalInt(numericTesting, a, b); + MarshalUInt(numericTesting, (uint32_t)a, (uint32_t)b); + MarshalLong(numericTesting, (int64_t)a, (int64_t)b); + MarshalULong(numericTesting, (uint64_t)a, (uint64_t)b); + MarshalFloat(numericTesting, (float)a / 100.f, (float)b / 100.f); + MarshalDouble(numericTesting, (double)a / 100.0, (double)b / 100.0); +} diff --git a/tests/src/Interop/COM/NativeClients/Primitives/StringTests.cpp b/tests/src/Interop/COM/NativeClients/Primitives/StringTests.cpp new file mode 100644 index 0000000000..a9dad99668 --- /dev/null +++ b/tests/src/Interop/COM/NativeClients/Primitives/StringTests.cpp @@ -0,0 +1,422 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include "ClientTests.h" +#include <vector> +#include <sstream> + +namespace +{ + template + < + typename CT, + void*(*STR_ALLOC)(size_t), + void(*STR_FREE)(void*) + > + class AnyStr + { + public: + AnyStr() : _lenBytes{ 0 } , _str{ nullptr } + { } + + explicit AnyStr(_In_z_ const char *str) + : _lenBytes{ (::strlen(str) + 1) * sizeof(CT) } + { + _str = (CT *)STR_ALLOC(_lenBytes); + CT *strLocal = _str; + + while (*str) + { + // [TODO] handle UTF8 + *strLocal = static_cast<CT>(*str++); + strLocal++; + } + *strLocal = CT{ '\0' }; + } + + // Concat strings + AnyStr(_In_ const AnyStr &l, _In_ const AnyStr &r) + : _lenBytes{ l._lenBytes + r._lenBytes - sizeof(CT) } // Remove duplicate null + { + _str = (CT *)STR_ALLOC(_lenBytes); + CT *strLocal = _str; + std::memcpy(strLocal, l._str, l._lenBytes - sizeof(CT)); // Ignore null + + size_t l_len = l.Length(); + std::memcpy(strLocal + l_len, r._str, r._lenBytes); + } + + AnyStr(_In_ const AnyStr &other) + : _lenBytes{ other._lenBytes } + , _str{ (CT *)STR_ALLOC(other._lenBytes) } + { + std::memcpy(_str, other._str, _lenBytes); + } + + AnyStr& operator=(_In_ const AnyStr &other) + { + AnyStr old{ std::move(*this) }; + AnyStr otherCopy{ other }; + (*this) = std::move(otherCopy); + return (*this); + } + + AnyStr(_Inout_ AnyStr &&other) + : _lenBytes{ other._lenBytes } + , _str{ other._str } + { + other._str = nullptr; + } + + AnyStr& operator=(_Inout_ AnyStr &&other) + { + AnyStr tmp{ std::move(*this) }; + _lenBytes = other._lenBytes; + _str = other._str; + other._str = nullptr; + return (*this); + } + + ~AnyStr() + { + if (_str != nullptr) + STR_FREE(_str); + } + + operator CT*() + { + return _str; + } + + operator const CT*() const + { + return _str; + } + + CT** operator &() + { + return &_str; + } + + bool operator==(_In_ const AnyStr &other) const + { + return EqualTo(other._str); + } + + bool operator!=(_In_ const AnyStr &other) const + { + return !(*this == other); + } + + void Attach(_In_z_ CT *data) + { + AnyStr tmp{ std::move(*this) }; + + CT *dataIter = data; + int len = 1; // Include 1 for null + while (*dataIter++) + ++len; + + _str = data; + _lenBytes = len * sizeof(CT); + } + + // String length _not_ including null + size_t Length() const + { + if (_lenBytes == 0) + return 0; + + return (_lenBytes - sizeof(CT)) / sizeof(CT); + } + + // String length including null in bytes + size_t LengthByte() const + { + return _lenBytes; + } + + bool AllAscii() const + { + const CT *c = _str; + const CT MaxAscii = (CT)0x7f; + while (*c) + { + if ((*c++) > MaxAscii) + return false; + } + + return true; + } + + bool EqualTo(_In_z_ const CT *str) const + { + const CT *tmp = str; + int len = 1; // Include 1 for null + while (*tmp++) + ++len; + + if (_lenBytes != (sizeof(CT) * len)) + return false; + + return (0 == std::memcmp(_str, str, _lenBytes)); + } + + HRESULT Reverse(_Inout_ AnyStr &res) const + { + AnyStr tmp{}; + + if (_lenBytes > 0) + { + tmp._lenBytes = _lenBytes; + tmp._str = (CT *)STR_ALLOC(_lenBytes); + if (tmp._str == nullptr) + return E_OUTOFMEMORY; + + ::memcpy(tmp._str, _str, _lenBytes); + std::reverse(tmp._str, tmp._str + Length()); + } + + res = std::move(tmp); + return S_OK; + } + + private: + size_t _lenBytes; + CT *_str; + }; + + // BSTR string + using BStr = AnyStr<OLECHAR, &CoreClrBstrAlloc, &CoreClrBstrFree>; + + // Wide string + using WStr = AnyStr<WCHAR, &CoreClrAlloc, &CoreClrFree>; + + // Narrow string + using NStr = AnyStr<CHAR, &CoreClrAlloc, &CoreClrFree>; + + template <typename STR> + std::vector<std::pair<STR, STR>> GetAddPairs() + { + std::vector<std::pair<STR, STR>> pairs; + + pairs.push_back({ STR{ "" }, STR{ "" } }); + pairs.push_back({ STR{ "" }, STR{ "def" } }); + pairs.push_back({ STR{ "abc" }, STR{ "" } }); + pairs.push_back({ STR{ "abc" }, STR{ "def" } }); + + // String marshalling is optimized where strings shorter than MAX_PATH are + // allocated on the stack. Longer strings have memory allocated for them. + pairs.push_back({ + STR{ "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901" }, + STR{ "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901" } + }); + + return pairs; + } + + template <typename STR> + std::vector<STR> GetReversableStrings() + { + std::vector<STR> rev; + + rev.push_back(STR{ "" }); + rev.push_back(STR{ "a" }); + rev.push_back(STR{ "abc" }); + rev.push_back(STR{ "reversable string" }); + + // Long string optimization validation + rev.push_back(STR{ "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901" }); + + return rev; + } + + void Marshal_LPString(_In_ IStringTesting* stringTesting) + { + ::printf("Marshal strings as LPStr\n"); + + HRESULT hr; + + auto pairs = GetAddPairs<NStr>(); + for (auto &p : pairs) + { + if (!p.first.AllAscii() || !p.second.AllAscii()) + { + // LPStr doesn't support non-ascii characters + continue; + } + + LPSTR tmp; + NStr expected{ p.first, p.second }; + THROW_IF_FAILED(stringTesting->raw_Add_LPStr(p.first, p.second, &tmp)); + + NStr actual; + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected.EqualTo(actual)); + } + + auto reversable = GetReversableStrings<NStr>(); + for (const auto &r : reversable) + { + if (!r.AllAscii()) + { + // LPStr doesn't support non-ascii characters + continue; + } + + LPSTR tmp; + NStr local{ r }; + + NStr actual; + NStr expected; + THROW_IF_FAILED(r.Reverse(expected)); + + THROW_IF_FAILED(stringTesting->raw_Reverse_LPStr(local, &tmp)); + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected == actual); + + THROW_IF_FAILED(stringTesting->raw_Reverse_LPStr_Ref(&local, &tmp)); + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected == actual); + THROW_FAIL_IF_FALSE(r == local); // Local should not be changed + + local = r; + THROW_IF_FAILED(stringTesting->raw_Reverse_LPStr_InRef(&local, &tmp)); + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected == actual); + THROW_FAIL_IF_FALSE(r == local); // Local should not be changed + + THROW_IF_FAILED(stringTesting->raw_Reverse_LPStr_Out(local, &tmp)); + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected == actual); + + actual = local; + tmp = actual; + THROW_IF_FAILED(stringTesting->raw_Reverse_LPStr_OutAttr(local, tmp)); // No-op for strings + THROW_FAIL_IF_FALSE(local == actual); + } + } + + void Marshal_LPWString(_In_ IStringTesting* stringTesting) + { + ::printf("Marshal strings as LPWStr\n"); + + HRESULT hr; + + auto pairs = GetAddPairs<WStr>(); + for (auto &p : pairs) + { + LPWSTR tmp; + WStr expected{ p.first, p.second }; + THROW_IF_FAILED(stringTesting->raw_Add_LPWStr(p.first, p.second, &tmp)); + + WStr actual; + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected.EqualTo(actual)); + } + + auto reversable = GetReversableStrings<WStr>(); + for (const auto &r : reversable) + { + LPWSTR tmp; + WStr local{ r }; + + WStr actual; + WStr expected; + THROW_IF_FAILED(r.Reverse(expected)); + + THROW_IF_FAILED(stringTesting->raw_Reverse_LPWStr(local, &tmp)); + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected == actual); + + THROW_IF_FAILED(stringTesting->raw_Reverse_LPWStr_Ref(&local, &tmp)); + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected == actual); + THROW_FAIL_IF_FALSE(r == local); // Local should not be changed + + local = r; + THROW_IF_FAILED(stringTesting->raw_Reverse_LPWStr_InRef(&local, &tmp)); + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected == actual); + THROW_FAIL_IF_FALSE(r == local); // Local should not be changed + + THROW_IF_FAILED(stringTesting->raw_Reverse_LPWStr_Out(local, &tmp)); + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected == actual); + + actual = local; + tmp = actual; + THROW_IF_FAILED(stringTesting->raw_Reverse_LPWStr_OutAttr(local, tmp)); // No-op for strings + THROW_FAIL_IF_FALSE(local == actual); + } + } + + void Marshal_BStrString(_In_ IStringTesting* stringTesting) + { + ::printf("Marshal strings as BStr\n"); + + HRESULT hr; + + auto pairs = GetAddPairs<BStr>(); + for (auto &p : pairs) + { + BSTR tmp; + BStr expected{ p.first, p.second }; + THROW_IF_FAILED(stringTesting->raw_Add_BStr(p.first, p.second, &tmp)); + + BStr actual; + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected.EqualTo(actual)); + } + + auto reversable = GetReversableStrings<BStr>(); + for (const auto &r : reversable) + { + BSTR tmp; + BStr local{ r }; + + BStr actual; + BStr expected; + THROW_IF_FAILED(r.Reverse(expected)); + + THROW_IF_FAILED(stringTesting->raw_Reverse_BStr(local, &tmp)); + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected == actual); + + THROW_IF_FAILED(stringTesting->raw_Reverse_BStr_Ref(&local, &tmp)); + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected == actual); + THROW_FAIL_IF_FALSE(r == local); // Local should not be changed + + local = r; + THROW_IF_FAILED(stringTesting->raw_Reverse_BStr_InRef(&local, &tmp)); + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected == actual); + THROW_FAIL_IF_FALSE(r == local); // Local should not be changed + + THROW_IF_FAILED(stringTesting->raw_Reverse_BStr_Out(local, &tmp)); + actual.Attach(tmp); + THROW_FAIL_IF_FALSE(expected == actual); + + actual = local; + tmp = actual; + THROW_IF_FAILED(stringTesting->raw_Reverse_BStr_OutAttr(local, tmp)); // No-op for strings + THROW_FAIL_IF_FALSE(local == actual); + } + } +} + +void Run_StringTests() +{ + HRESULT hr; + + CoreShimComActivation csact{ W("NETServer.dll"), W("StringTesting") }; + + ComSmartPtr<IStringTesting> stringTesting; + THROW_IF_FAILED(::CoCreateInstance(CLSID_StringTesting, nullptr, CLSCTX_INPROC, IID_IStringTesting, (void**)&stringTesting)); + + Marshal_LPString(stringTesting); + Marshal_LPWString(stringTesting); + Marshal_BStrString(stringTesting); +} diff --git a/tests/src/Interop/COM/NativeServer/ArrayTesting.h b/tests/src/Interop/COM/NativeServer/ArrayTesting.h index 6939762a8b..27d02396a2 100644 --- a/tests/src/Interop/COM/NativeServer/ArrayTesting.h +++ b/tests/src/Interop/COM/NativeServer/ArrayTesting.h @@ -20,7 +20,7 @@ private: return (t / l); } template<VARTYPE E> - HRESULT Mean(SAFEARRAY *d, long *l, double *r) + HRESULT Mean(SAFEARRAY *d, int *l, double *r) { HRESULT hr; @@ -74,7 +74,7 @@ private: public: // IArrayTesting DEF_RAWFUNC(Mean_Byte_LP_PreLen)( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ unsigned char * d, /*[out,retval]*/ double * pRetVal) { @@ -84,7 +84,7 @@ public: // IArrayTesting return S_OK; } DEF_RAWFUNC(Mean_Short_LP_PreLen)( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ short * d, /*[out,retval]*/ double * pRetVal) { @@ -94,7 +94,7 @@ public: // IArrayTesting return S_OK; } DEF_RAWFUNC(Mean_UShort_LP_PreLen)( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ unsigned short * d, /*[out,retval]*/ double * pRetVal) { @@ -104,8 +104,8 @@ public: // IArrayTesting return S_OK; } DEF_RAWFUNC(Mean_Int_LP_PreLen)( - /*[in]*/ long len, - /*[in]*/ long * d, + /*[in]*/ int len, + /*[in]*/ int * d, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -114,8 +114,8 @@ public: // IArrayTesting return S_OK; } DEF_RAWFUNC(Mean_UInt_LP_PreLen)( - /*[in]*/ long len, - /*[in]*/ unsigned long * d, + /*[in]*/ int len, + /*[in]*/ unsigned int * d, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -124,7 +124,7 @@ public: // IArrayTesting return S_OK; } DEF_RAWFUNC(Mean_Long_LP_PreLen)( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ __int64 * d, /*[out,retval]*/ double * pRetVal) { @@ -134,7 +134,7 @@ public: // IArrayTesting return S_OK; } DEF_RAWFUNC(Mean_ULong_LP_PreLen)( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ unsigned __int64 * d, /*[out,retval]*/ double * pRetVal) { @@ -144,7 +144,7 @@ public: // IArrayTesting return S_OK; } DEF_RAWFUNC(Mean_Float_LP_PreLen)( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ float * d, /*[out,retval]*/ double * pRetVal) { @@ -154,7 +154,7 @@ public: // IArrayTesting return S_OK; } DEF_RAWFUNC(Mean_Double_LP_PreLen)( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ double * d, /*[out,retval]*/ double * pRetVal) { @@ -165,7 +165,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_Byte_LP_PostLen)( /*[in]*/ unsigned char * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -175,7 +175,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_Short_LP_PostLen)( /*[in]*/ short * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -185,7 +185,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_UShort_LP_PostLen)( /*[in]*/ unsigned short * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -194,8 +194,8 @@ public: // IArrayTesting return S_OK; } DEF_RAWFUNC(Mean_Int_LP_PostLen)( - /*[in]*/ long * d, - /*[in]*/ long len, + /*[in]*/ int * d, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -204,8 +204,8 @@ public: // IArrayTesting return S_OK; } DEF_RAWFUNC(Mean_UInt_LP_PostLen)( - /*[in]*/ unsigned long * d, - /*[in]*/ long len, + /*[in]*/ unsigned int * d, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -215,7 +215,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_Long_LP_PostLen)( /*[in]*/ __int64 * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -225,7 +225,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_ULong_LP_PostLen)( /*[in]*/ unsigned __int64 * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -235,7 +235,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_Float_LP_PostLen)( /*[in]*/ float * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -245,7 +245,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_Double_LP_PostLen)( /*[in]*/ double * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -255,7 +255,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_Byte_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -264,7 +264,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_Short_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -273,7 +273,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_UShort_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -282,7 +282,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_Int_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -291,7 +291,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_UInt_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -300,7 +300,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_Long_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -309,7 +309,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_ULong_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -318,7 +318,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_Float_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) @@ -327,7 +327,7 @@ public: // IArrayTesting } DEF_RAWFUNC(Mean_Double_SafeArray_OutLen)( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal) { if (pRetVal == nullptr) diff --git a/tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h b/tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h index 6dd76490c7..2b1276c989 100644 --- a/tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h +++ b/tests/src/Interop/COM/NativeServer/ErrorMarshalTesting.h @@ -10,12 +10,13 @@ class ErrorMarshalTesting : public UnknownImpl, public IErrorMarshalTesting { public: // IErrorMarshalTesting DEF_RAWFUNC(Throw_HResult)( - /*[in]*/ long hresultToReturn) + /*[in]*/ int hresultToReturn) { return HRESULT{ hresultToReturn }; } - long STDMETHODCALLTYPE Return_As_HResult( - /*[in]*/ long hresultToReturn) + + int STDMETHODCALLTYPE Return_As_HResult( + /*[in]*/ int hresultToReturn) { return hresultToReturn; } diff --git a/tests/src/Interop/COM/NativeServer/NumericTesting.h b/tests/src/Interop/COM/NativeServer/NumericTesting.h index 555a38d0c4..1f4acf9b0f 100644 --- a/tests/src/Interop/COM/NativeServer/NumericTesting.h +++ b/tests/src/Interop/COM/NativeServer/NumericTesting.h @@ -36,17 +36,17 @@ public: return S_OK; } DEF_RAWFUNC(Add_Int)( - /*[in]*/ long a, - /*[in]*/ long b, - /*[out,retval]*/ long * pRetVal) + /*[in]*/ int a, + /*[in]*/ int b, + /*[out,retval]*/ int * pRetVal) { *pRetVal = a + b; return S_OK; } DEF_RAWFUNC(Add_UInt)( - /*[in]*/ unsigned long a, - /*[in]*/ unsigned long b, - /*[out,retval]*/ unsigned long * pRetVal) + /*[in]*/ unsigned int a, + /*[in]*/ unsigned int b, + /*[out,retval]*/ unsigned int * pRetVal) { *pRetVal = a + b; return S_OK; @@ -114,9 +114,9 @@ public: return S_OK; } DEF_RAWFUNC(Add_Int_Ref)( - /*[in]*/ long a, - /*[in]*/ long b, - /*[in,out]*/ long * c) + /*[in]*/ int a, + /*[in]*/ int b, + /*[in,out]*/ int * c) { if (*c != std::numeric_limits<std::remove_reference<decltype(*c)>::type>::max()) return E_UNEXPECTED; @@ -124,9 +124,9 @@ public: return S_OK; } DEF_RAWFUNC(Add_UInt_Ref)( - /*[in]*/ unsigned long a, - /*[in]*/ unsigned long b, - /*[in,out]*/ unsigned long * c) + /*[in]*/ unsigned int a, + /*[in]*/ unsigned int b, + /*[in,out]*/ unsigned int * c) { if (*c != std::numeric_limits<std::remove_reference<decltype(*c)>::type>::max()) return E_UNEXPECTED; @@ -198,17 +198,17 @@ public: return S_OK; } DEF_RAWFUNC(Add_Int_Out)( - /*[in]*/ long a, - /*[in]*/ long b, - /*[out]*/ long * c) + /*[in]*/ int a, + /*[in]*/ int b, + /*[out]*/ int * c) { *c = a + b; return S_OK; } DEF_RAWFUNC(Add_UInt_Out)( - /*[in]*/ unsigned long a, - /*[in]*/ unsigned long b, - /*[out]*/ unsigned long * c) + /*[in]*/ unsigned int a, + /*[in]*/ unsigned int b, + /*[out]*/ unsigned int * c) { *c = a + b; return S_OK; diff --git a/tests/src/Interop/COM/NativeServer/Servers.h b/tests/src/Interop/COM/NativeServer/Servers.h index bcfdbe2c5f..4f279e0a14 100644 --- a/tests/src/Interop/COM/NativeServer/Servers.h +++ b/tests/src/Interop/COM/NativeServer/Servers.h @@ -5,6 +5,7 @@ #pragma once #include <xplatform.h> +#include <cassert> //#import "Server.Contract.tlb" no_namespace #include <Server.Contracts.tlh> @@ -25,6 +26,29 @@ class DECLSPEC_UUID("71CF5C45-106C-4B32-B418-43A463C6041F") ErrorMarshalTesting; #define IID_IStringTesting __uuidof(IStringTesting) #define IID_IErrorMarshalTesting __uuidof(IErrorMarshalTesting) +// Class used for COM activation when using CoreShim +struct CoreShimComActivation +{ + CoreShimComActivation(_In_z_ const WCHAR *assemblyName, _In_z_ const WCHAR *typeName) + { + assert(assemblyName && typeName); + Set(assemblyName, typeName); + } + + ~CoreShimComActivation() + { + Set(nullptr, nullptr); + } + +private: + void Set(_In_opt_z_ const WCHAR *assemblyName, _In_opt_z_ const WCHAR *typeName) + { + // See CoreShim.h for usage of environment variables + ::SetEnvironmentVariableW(W("CORESHIM_COMACT_ASSEMBLYNAME"), assemblyName); + ::SetEnvironmentVariableW(W("CORESHIM_COMACT_TYPENAME"), typeName); + } +}; + #ifndef COM_CLIENT #include "ComHelpers.h" diff --git a/tests/src/Interop/COM/ServerContracts/Primitives.cs b/tests/src/Interop/COM/ServerContracts/Primitives.cs index cc6a30344b..0714047003 100644 --- a/tests/src/Interop/COM/ServerContracts/Primitives.cs +++ b/tests/src/Interop/COM/ServerContracts/Primitives.cs @@ -51,25 +51,25 @@ namespace Server.Contract [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IArrayTesting { - double Mean_Byte_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] byte[] d); - double Mean_Short_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] short[] d); - double Mean_UShort_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] ushort[] d); - double Mean_Int_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] int[] d); - double Mean_UInt_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] uint[] d); - double Mean_Long_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] long[] d); - double Mean_ULong_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] ulong[] d); - double Mean_Float_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] float[] d); - double Mean_Double_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray)] double[] d); - - double Mean_Byte_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] byte[] d, int len); - double Mean_Short_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] short[] d, int len); - double Mean_UShort_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] ushort[] d, int len); - double Mean_Int_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] int[] d, int len); - double Mean_UInt_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] uint[] d, int len); - double Mean_Long_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] long[] d, int len); - double Mean_ULong_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] ulong[] d, int len); - double Mean_Float_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] float[] d, int len); - double Mean_Double_LP_PostLen([MarshalAs(UnmanagedType.LPArray)] double[] d, int len); + double Mean_Byte_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] byte[] d); + double Mean_Short_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] short[] d); + double Mean_UShort_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] ushort[] d); + double Mean_Int_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] int[] d); + double Mean_UInt_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] uint[] d); + double Mean_Long_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] long[] d); + double Mean_ULong_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] ulong[] d); + double Mean_Float_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] float[] d); + double Mean_Double_LP_PreLen(int len, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] double[] d); + + double Mean_Byte_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] byte[] d, int len); + double Mean_Short_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] short[] d, int len); + double Mean_UShort_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] ushort[] d, int len); + double Mean_Int_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] int[] d, int len); + double Mean_UInt_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] uint[] d, int len); + double Mean_Long_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] long[] d, int len); + double Mean_ULong_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] ulong[] d, int len); + double Mean_Float_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] float[] d, int len); + double Mean_Double_LP_PostLen([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] double[] d, int len); double Mean_Byte_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] byte[] d, out int len); double Mean_Short_SafeArray_OutLen([MarshalAs(UnmanagedType.SafeArray)] short[] d, out int len); diff --git a/tests/src/Interop/COM/ServerContracts/Server.Contracts.tlh b/tests/src/Interop/COM/ServerContracts/Server.Contracts.tlh index 9bc826d766..412d352156 100644 --- a/tests/src/Interop/COM/ServerContracts/Server.Contracts.tlh +++ b/tests/src/Interop/COM/ServerContracts/Server.Contracts.tlh @@ -49,12 +49,12 @@ INumericTesting : IUnknown unsigned short Add_UShort ( unsigned short a, unsigned short b ); - long Add_Int ( - long a, - long b ); - unsigned long Add_UInt ( - unsigned long a, - unsigned long b ); + int Add_Int ( + int a, + int b ); + unsigned int Add_UInt ( + unsigned int a, + unsigned int b ); __int64 Add_Long ( __int64 a, __int64 b ); @@ -80,13 +80,13 @@ INumericTesting : IUnknown unsigned short b, unsigned short * c ); HRESULT Add_Int_Ref ( - long a, - long b, - long * c ); + int a, + int b, + int * c ); HRESULT Add_UInt_Ref ( - unsigned long a, - unsigned long b, - unsigned long * c ); + unsigned int a, + unsigned int b, + unsigned int * c ); HRESULT Add_Long_Ref ( __int64 a, __int64 b, @@ -116,13 +116,13 @@ INumericTesting : IUnknown unsigned short b, unsigned short * c ); HRESULT Add_Int_Out ( - long a, - long b, - long * c ); + int a, + int b, + int * c ); HRESULT Add_UInt_Out ( - unsigned long a, - unsigned long b, - unsigned long * c ); + unsigned int a, + unsigned int b, + unsigned int * c ); HRESULT Add_Long_Out ( __int64 a, __int64 b, @@ -157,13 +157,13 @@ INumericTesting : IUnknown /*[in]*/ unsigned short b, /*[out,retval]*/ unsigned short * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Add_Int ( - /*[in]*/ long a, - /*[in]*/ long b, - /*[out,retval]*/ long * pRetVal ) = 0; + /*[in]*/ int a, + /*[in]*/ int b, + /*[out,retval]*/ int * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Add_UInt ( - /*[in]*/ unsigned long a, - /*[in]*/ unsigned long b, - /*[out,retval]*/ unsigned long * pRetVal ) = 0; + /*[in]*/ unsigned int a, + /*[in]*/ unsigned int b, + /*[out,retval]*/ unsigned int * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Add_Long ( /*[in]*/ __int64 a, /*[in]*/ __int64 b, @@ -193,13 +193,13 @@ INumericTesting : IUnknown /*[in]*/ unsigned short b, /*[in,out]*/ unsigned short * c ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Add_Int_Ref ( - /*[in]*/ long a, - /*[in]*/ long b, - /*[in,out]*/ long * c ) = 0; + /*[in]*/ int a, + /*[in]*/ int b, + /*[in,out]*/ int * c ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Add_UInt_Ref ( - /*[in]*/ unsigned long a, - /*[in]*/ unsigned long b, - /*[in,out]*/ unsigned long * c ) = 0; + /*[in]*/ unsigned int a, + /*[in]*/ unsigned int b, + /*[in,out]*/ unsigned int * c ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Add_Long_Ref ( /*[in]*/ __int64 a, /*[in]*/ __int64 b, @@ -229,13 +229,13 @@ INumericTesting : IUnknown /*[in]*/ unsigned short b, /*[out]*/ unsigned short * c ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Add_Int_Out ( - /*[in]*/ long a, - /*[in]*/ long b, - /*[out]*/ long * c ) = 0; + /*[in]*/ int a, + /*[in]*/ int b, + /*[out]*/ int * c ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Add_UInt_Out ( - /*[in]*/ unsigned long a, - /*[in]*/ unsigned long b, - /*[out]*/ unsigned long * c ) = 0; + /*[in]*/ unsigned int a, + /*[in]*/ unsigned int b, + /*[out]*/ unsigned int * c ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Add_Long_Out ( /*[in]*/ __int64 a, /*[in]*/ __int64 b, @@ -262,198 +262,198 @@ IArrayTesting : IUnknown // double Mean_Byte_LP_PreLen ( - long len, + int len, unsigned char * d ); double Mean_Short_LP_PreLen ( - long len, + int len, short * d ); double Mean_UShort_LP_PreLen ( - long len, + int len, unsigned short * d ); double Mean_Int_LP_PreLen ( - long len, - long * d ); + int len, + int * d ); double Mean_UInt_LP_PreLen ( - long len, - unsigned long * d ); + int len, + unsigned int * d ); double Mean_Long_LP_PreLen ( - long len, + int len, __int64 * d ); double Mean_ULong_LP_PreLen ( - long len, + int len, unsigned __int64 * d ); double Mean_Float_LP_PreLen ( - long len, + int len, float * d ); double Mean_Double_LP_PreLen ( - long len, + int len, double * d ); double Mean_Byte_LP_PostLen ( unsigned char * d, - long len ); + int len ); double Mean_Short_LP_PostLen ( short * d, - long len ); + int len ); double Mean_UShort_LP_PostLen ( unsigned short * d, - long len ); + int len ); double Mean_Int_LP_PostLen ( - long * d, - long len ); + int * d, + int len ); double Mean_UInt_LP_PostLen ( - unsigned long * d, - long len ); + unsigned int * d, + int len ); double Mean_Long_LP_PostLen ( __int64 * d, - long len ); + int len ); double Mean_ULong_LP_PostLen ( unsigned __int64 * d, - long len ); + int len ); double Mean_Float_LP_PostLen ( float * d, - long len ); + int len ); double Mean_Double_LP_PostLen ( double * d, - long len ); + int len ); double Mean_Byte_SafeArray_OutLen ( SAFEARRAY * d, - long * len ); + int * len ); double Mean_Short_SafeArray_OutLen ( SAFEARRAY * d, - long * len ); + int * len ); double Mean_UShort_SafeArray_OutLen ( SAFEARRAY * d, - long * len ); + int * len ); double Mean_Int_SafeArray_OutLen ( SAFEARRAY * d, - long * len ); + int * len ); double Mean_UInt_SafeArray_OutLen ( SAFEARRAY * d, - long * len ); + int * len ); double Mean_Long_SafeArray_OutLen ( SAFEARRAY * d, - long * len ); + int * len ); double Mean_ULong_SafeArray_OutLen ( SAFEARRAY * d, - long * len ); + int * len ); double Mean_Float_SafeArray_OutLen ( SAFEARRAY * d, - long * len ); + int * len ); double Mean_Double_SafeArray_OutLen ( SAFEARRAY * d, - long * len ); + int * len ); // // Raw methods provided by interface // virtual HRESULT STDMETHODCALLTYPE raw_Mean_Byte_LP_PreLen ( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ unsigned char * d, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Short_LP_PreLen ( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ short * d, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_UShort_LP_PreLen ( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ unsigned short * d, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Int_LP_PreLen ( - /*[in]*/ long len, - /*[in]*/ long * d, + /*[in]*/ int len, + /*[in]*/ int * d, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_UInt_LP_PreLen ( - /*[in]*/ long len, - /*[in]*/ unsigned long * d, + /*[in]*/ int len, + /*[in]*/ unsigned int * d, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Long_LP_PreLen ( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ __int64 * d, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_ULong_LP_PreLen ( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ unsigned __int64 * d, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Float_LP_PreLen ( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ float * d, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Double_LP_PreLen ( - /*[in]*/ long len, + /*[in]*/ int len, /*[in]*/ double * d, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Byte_LP_PostLen ( /*[in]*/ unsigned char * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Short_LP_PostLen ( /*[in]*/ short * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_UShort_LP_PostLen ( /*[in]*/ unsigned short * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Int_LP_PostLen ( - /*[in]*/ long * d, - /*[in]*/ long len, + /*[in]*/ int * d, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_UInt_LP_PostLen ( - /*[in]*/ unsigned long * d, - /*[in]*/ long len, + /*[in]*/ unsigned int * d, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Long_LP_PostLen ( /*[in]*/ __int64 * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_ULong_LP_PostLen ( /*[in]*/ unsigned __int64 * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Float_LP_PostLen ( /*[in]*/ float * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Double_LP_PostLen ( /*[in]*/ double * d, - /*[in]*/ long len, + /*[in]*/ int len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Byte_SafeArray_OutLen ( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Short_SafeArray_OutLen ( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_UShort_SafeArray_OutLen ( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Int_SafeArray_OutLen ( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_UInt_SafeArray_OutLen ( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Long_SafeArray_OutLen ( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_ULong_SafeArray_OutLen ( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Float_SafeArray_OutLen ( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal ) = 0; virtual HRESULT STDMETHODCALLTYPE raw_Mean_Double_SafeArray_OutLen ( /*[in]*/ SAFEARRAY * d, - /*[out]*/ long * len, + /*[out]*/ int * len, /*[out,retval]*/ double * pRetVal ) = 0; }; @@ -635,16 +635,16 @@ IErrorMarshalTesting : IUnknown // HRESULT Throw_HResult ( - long hresultToReturn ); + int hresultToReturn ); // // Raw methods provided by interface // virtual HRESULT STDMETHODCALLTYPE raw_Throw_HResult ( - /*[in]*/ long hresultToReturn ) = 0; - virtual long STDMETHODCALLTYPE Return_As_HResult ( - /*[in]*/ long hresultToReturn ) = 0; + /*[in]*/ int hresultToReturn ) = 0; + virtual int STDMETHODCALLTYPE Return_As_HResult ( + /*[in]*/ int hresultToReturn ) = 0; }; // diff --git a/tests/src/Interop/COM/ServerContracts/Server.Contracts.tli b/tests/src/Interop/COM/ServerContracts/Server.Contracts.tli index a419c654e6..94046af919 100644 --- a/tests/src/Interop/COM/ServerContracts/Server.Contracts.tli +++ b/tests/src/Interop/COM/ServerContracts/Server.Contracts.tli @@ -27,15 +27,15 @@ inline unsigned short INumericTesting::Add_UShort ( unsigned short a, unsigned s return _result; } -inline long INumericTesting::Add_Int ( long a, long b ) { - long _result = 0; +inline int INumericTesting::Add_Int ( int a, int b ) { + int _result = 0; HRESULT _hr = raw_Add_Int(a, b, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline unsigned long INumericTesting::Add_UInt ( unsigned long a, unsigned long b ) { - unsigned long _result = 0; +inline unsigned int INumericTesting::Add_UInt ( unsigned int a, unsigned int b ) { + unsigned int _result = 0; HRESULT _hr = raw_Add_UInt(a, b, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; @@ -87,13 +87,13 @@ inline HRESULT INumericTesting::Add_UShort_Ref ( unsigned short a, unsigned shor return _hr; } -inline HRESULT INumericTesting::Add_Int_Ref ( long a, long b, long * c ) { +inline HRESULT INumericTesting::Add_Int_Ref ( int a, int b, int * c ) { HRESULT _hr = raw_Add_Int_Ref(a, b, c); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _hr; } -inline HRESULT INumericTesting::Add_UInt_Ref ( unsigned long a, unsigned long b, unsigned long * c ) { +inline HRESULT INumericTesting::Add_UInt_Ref ( unsigned int a, unsigned int b, unsigned int * c ) { HRESULT _hr = raw_Add_UInt_Ref(a, b, c); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _hr; @@ -141,13 +141,13 @@ inline HRESULT INumericTesting::Add_UShort_Out ( unsigned short a, unsigned shor return _hr; } -inline HRESULT INumericTesting::Add_Int_Out ( long a, long b, long * c ) { +inline HRESULT INumericTesting::Add_Int_Out ( int a, int b, int * c ) { HRESULT _hr = raw_Add_Int_Out(a, b, c); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _hr; } -inline HRESULT INumericTesting::Add_UInt_Out ( unsigned long a, unsigned long b, unsigned long * c ) { +inline HRESULT INumericTesting::Add_UInt_Out ( unsigned int a, unsigned int b, unsigned int * c ) { HRESULT _hr = raw_Add_UInt_Out(a, b, c); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _hr; @@ -181,189 +181,189 @@ inline HRESULT INumericTesting::Add_Double_Out ( double a, double b, double * c // interface IArrayTesting wrapper method implementations // -inline double IArrayTesting::Mean_Byte_LP_PreLen ( long len, unsigned char * d ) { +inline double IArrayTesting::Mean_Byte_LP_PreLen ( int len, unsigned char * d ) { double _result = 0; HRESULT _hr = raw_Mean_Byte_LP_PreLen(len, d, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Short_LP_PreLen ( long len, short * d ) { +inline double IArrayTesting::Mean_Short_LP_PreLen ( int len, short * d ) { double _result = 0; HRESULT _hr = raw_Mean_Short_LP_PreLen(len, d, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_UShort_LP_PreLen ( long len, unsigned short * d ) { +inline double IArrayTesting::Mean_UShort_LP_PreLen ( int len, unsigned short * d ) { double _result = 0; HRESULT _hr = raw_Mean_UShort_LP_PreLen(len, d, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Int_LP_PreLen ( long len, long * d ) { +inline double IArrayTesting::Mean_Int_LP_PreLen ( int len, int * d ) { double _result = 0; HRESULT _hr = raw_Mean_Int_LP_PreLen(len, d, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_UInt_LP_PreLen ( long len, unsigned long * d ) { +inline double IArrayTesting::Mean_UInt_LP_PreLen ( int len, unsigned int * d ) { double _result = 0; HRESULT _hr = raw_Mean_UInt_LP_PreLen(len, d, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Long_LP_PreLen ( long len, __int64 * d ) { +inline double IArrayTesting::Mean_Long_LP_PreLen ( int len, __int64 * d ) { double _result = 0; HRESULT _hr = raw_Mean_Long_LP_PreLen(len, d, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_ULong_LP_PreLen ( long len, unsigned __int64 * d ) { +inline double IArrayTesting::Mean_ULong_LP_PreLen ( int len, unsigned __int64 * d ) { double _result = 0; HRESULT _hr = raw_Mean_ULong_LP_PreLen(len, d, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Float_LP_PreLen ( long len, float * d ) { +inline double IArrayTesting::Mean_Float_LP_PreLen ( int len, float * d ) { double _result = 0; HRESULT _hr = raw_Mean_Float_LP_PreLen(len, d, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Double_LP_PreLen ( long len, double * d ) { +inline double IArrayTesting::Mean_Double_LP_PreLen ( int len, double * d ) { double _result = 0; HRESULT _hr = raw_Mean_Double_LP_PreLen(len, d, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Byte_LP_PostLen ( unsigned char * d, long len ) { +inline double IArrayTesting::Mean_Byte_LP_PostLen ( unsigned char * d, int len ) { double _result = 0; HRESULT _hr = raw_Mean_Byte_LP_PostLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Short_LP_PostLen ( short * d, long len ) { +inline double IArrayTesting::Mean_Short_LP_PostLen ( short * d, int len ) { double _result = 0; HRESULT _hr = raw_Mean_Short_LP_PostLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_UShort_LP_PostLen ( unsigned short * d, long len ) { +inline double IArrayTesting::Mean_UShort_LP_PostLen ( unsigned short * d, int len ) { double _result = 0; HRESULT _hr = raw_Mean_UShort_LP_PostLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Int_LP_PostLen ( long * d, long len ) { +inline double IArrayTesting::Mean_Int_LP_PostLen ( int * d, int len ) { double _result = 0; HRESULT _hr = raw_Mean_Int_LP_PostLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_UInt_LP_PostLen ( unsigned long * d, long len ) { +inline double IArrayTesting::Mean_UInt_LP_PostLen ( unsigned int * d, int len ) { double _result = 0; HRESULT _hr = raw_Mean_UInt_LP_PostLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Long_LP_PostLen ( __int64 * d, long len ) { +inline double IArrayTesting::Mean_Long_LP_PostLen ( __int64 * d, int len ) { double _result = 0; HRESULT _hr = raw_Mean_Long_LP_PostLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_ULong_LP_PostLen ( unsigned __int64 * d, long len ) { +inline double IArrayTesting::Mean_ULong_LP_PostLen ( unsigned __int64 * d, int len ) { double _result = 0; HRESULT _hr = raw_Mean_ULong_LP_PostLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Float_LP_PostLen ( float * d, long len ) { +inline double IArrayTesting::Mean_Float_LP_PostLen ( float * d, int len ) { double _result = 0; HRESULT _hr = raw_Mean_Float_LP_PostLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Double_LP_PostLen ( double * d, long len ) { +inline double IArrayTesting::Mean_Double_LP_PostLen ( double * d, int len ) { double _result = 0; HRESULT _hr = raw_Mean_Double_LP_PostLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Byte_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { +inline double IArrayTesting::Mean_Byte_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { double _result = 0; HRESULT _hr = raw_Mean_Byte_SafeArray_OutLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Short_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { +inline double IArrayTesting::Mean_Short_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { double _result = 0; HRESULT _hr = raw_Mean_Short_SafeArray_OutLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_UShort_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { +inline double IArrayTesting::Mean_UShort_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { double _result = 0; HRESULT _hr = raw_Mean_UShort_SafeArray_OutLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Int_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { +inline double IArrayTesting::Mean_Int_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { double _result = 0; HRESULT _hr = raw_Mean_Int_SafeArray_OutLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_UInt_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { +inline double IArrayTesting::Mean_UInt_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { double _result = 0; HRESULT _hr = raw_Mean_UInt_SafeArray_OutLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Long_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { +inline double IArrayTesting::Mean_Long_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { double _result = 0; HRESULT _hr = raw_Mean_Long_SafeArray_OutLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_ULong_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { +inline double IArrayTesting::Mean_ULong_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { double _result = 0; HRESULT _hr = raw_Mean_ULong_SafeArray_OutLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Float_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { +inline double IArrayTesting::Mean_Float_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { double _result = 0; HRESULT _hr = raw_Mean_Float_SafeArray_OutLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _result; } -inline double IArrayTesting::Mean_Double_SafeArray_OutLen ( SAFEARRAY * d, long * len ) { +inline double IArrayTesting::Mean_Double_SafeArray_OutLen ( SAFEARRAY * d, int * len ) { double _result = 0; HRESULT _hr = raw_Mean_Double_SafeArray_OutLen(d, len, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); @@ -564,7 +564,7 @@ inline HRESULT IStringTesting::Reverse_BStr_OutAttr ( _bstr_t a, _bstr_t b ) { // interface IErrorMarshalTesting wrapper method implementations // -inline HRESULT IErrorMarshalTesting::Throw_HResult ( long hresultToReturn ) { +inline HRESULT IErrorMarshalTesting::Throw_HResult ( int hresultToReturn ) { HRESULT _hr = raw_Throw_HResult(hresultToReturn); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _hr; diff --git a/tests/src/Interop/Interop.settings.targets b/tests/src/Interop/Interop.settings.targets index 50e37af67f..df05c154b0 100644 --- a/tests/src/Interop/Interop.settings.targets +++ b/tests/src/Interop/Interop.settings.targets @@ -1,6 +1,7 @@ <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!-- Properties for all Interop managed test assets --> <PropertyGroup> + <InteropCommonDir>$(MSBuildThisFileDirectory)common/</InteropCommonDir> </PropertyGroup> <!-- Environment properties --> @@ -9,6 +10,6 @@ <!-- Required source files --> <ItemGroup> - <Compile Include="$(MSBuildThisFileDirectory)\common\Assertion.cs"/> + <Compile Condition="'$(IgnoreInteropAssertionFile)' != 'true'" Include="$(InteropCommonDir)Assertion.cs"/> </ItemGroup> </Project> diff --git a/tests/src/Interop/common/ExeLauncherProgram.cs b/tests/src/Interop/common/ExeLauncherProgram.cs new file mode 100644 index 0000000000..7f643f3d71 --- /dev/null +++ b/tests/src/Interop/common/ExeLauncherProgram.cs @@ -0,0 +1,69 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; + +/// <summary> +/// This class is used for creating a test that has an entry point +/// that is not the test itself. For example a test that starts from +/// a native exe instead of a managed entry point. +/// </summary> +public class Program +{ + static int Main(string[] noArgs) + { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + { + Console.WriteLine($"Exe launcher only supported on Windows environments..."); + return 100; + } + + string workingDir = Environment.CurrentDirectory; + Console.WriteLine($"Searching for exe to launch in {workingDir}..."); + + Assembly thisAssem = Assembly.GetEntryAssembly(); + string startExe = string.Empty; + foreach (string exeMaybe in Directory.EnumerateFiles(workingDir, "*.exe")) + { + // This entry point is _not_ an option + if (exeMaybe.Equals(thisAssem.Location, StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + startExe = exeMaybe; + break; + } + + if (string.IsNullOrEmpty(startExe)) + { + throw new Exception("Unable to find start EXE"); + } + + var startInfo = new ProcessStartInfo() + { + FileName = startExe, + + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true + }; + + Console.WriteLine($"Launching '{startExe}'..."); + using (Process p = Process.Start(startInfo)) + { + p.OutputDataReceived += (_, args) => Console.WriteLine(args.Data); + p.BeginOutputReadLine(); + + p.ErrorDataReceived += (_, args) => Console.Error.WriteLine(args.Data); + p.BeginErrorReadLine(); + + p.WaitForExit(); + return p.ExitCode; + } + } +}
\ No newline at end of file diff --git a/tests/src/Interop/common/xplatform.h b/tests/src/Interop/common/xplatform.h index e0b939eb60..94a693e384 100644 --- a/tests/src/Interop/common/xplatform.h +++ b/tests/src/Interop/common/xplatform.h @@ -36,6 +36,7 @@ // include #ifdef _WIN32 + #define NOMINMAX #include <windows.h> #include <combaseapi.h> @@ -95,6 +96,28 @@ inline void CoreClrFree(void *p) #endif } +inline void *CoreClrBstrAlloc(size_t cb) +{ +#ifdef _WIN32 + // A null is automatically applied in the SysAllocStringByteLen API. + // Remove a single OLECHAR for the implied null. + // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/oleauto/nf-oleauto-sysallocstringbytelen + if (cb >= sizeof(OLECHAR)) + cb -= sizeof(OLECHAR); + + return ::SysAllocStringByteLen(nullptr, static_cast<UINT>(cb)); +#else + return nullptr; +#endif +} + +inline void CoreClrBstrFree(void *p) +{ +#ifdef _WIN32 + return ::SysFreeString((BSTR)p); +#endif +} + // redirected types not-windows only #ifndef _WIN32 |