Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Add test for marshalling ArgIterators on Windows #20888

Merged
merged 14 commits into from Nov 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions tests/src/Interop/CMakeLists.txt
Expand Up @@ -46,6 +46,7 @@ add_subdirectory(DllImportAttribute/Simple)
add_subdirectory(ExecInDefAppDom)

if(WIN32)
add_subdirectory(PInvoke/Varargs)
add_subdirectory(PInvoke/NativeCallManagedComVisible)
# This test doesn't necessarily need to be Windows-only, but the implementation is very tied to Windows APIs
add_subdirectory(PInvoke/DateTime)
Expand Down
11 changes: 11 additions & 0 deletions tests/src/Interop/PInvoke/Varargs/CMakeLists.txt
@@ -0,0 +1,11 @@
cmake_minimum_required (VERSION 2.6)
project (VarargsNative)
include_directories(${INC_PLATFORM_DIR})
set(SOURCES VarargsNative.cpp )

# add the executable
add_library (VarargsNative SHARED ${SOURCES})
target_link_libraries(VarargsNative ${LINK_LIBRARIES_ADDITIONAL})

# add the install targets
install (TARGETS VarargsNative DESTINATION bin)
19 changes: 19 additions & 0 deletions tests/src/Interop/PInvoke/Varargs/VarargsNative.cpp
@@ -0,0 +1,19 @@
// 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 <stdarg.h>

extern "C" DLL_EXPORT void __cdecl TestVarArgs(LPWSTR formattedString, SIZE_T bufferSize, LPCWSTR format, ...)
{
va_list args;
va_start(args, format);

vswprintf_s(formattedString, bufferSize, format, args);
}

extern "C" DLL_EXPORT void STDMETHODCALLTYPE TestArgIterator(LPWSTR formattedString, SIZE_T bufferSize, LPCWSTR format, va_list args)
{
vswprintf_s(formattedString, bufferSize, format, args);
}
59 changes: 59 additions & 0 deletions tests/src/Interop/PInvoke/Varargs/VarargsTest.cs
@@ -0,0 +1,59 @@
// 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.Security;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using TestLibrary;

namespace PInvokeTests
{
class VarargsTest
{
[DllImport("VarargsNative", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern void TestVarArgs(StringBuilder builder, IntPtr bufferSize, string formatString, __arglist);

[DllImport("VarargsNative", CharSet = CharSet.Unicode)]
private static extern void TestArgIterator(StringBuilder builder, IntPtr bufferSize, string formatString, ArgIterator arguments);

private static void TestArgIteratorWrapper(StringBuilder builder, IntPtr bufferSize, string formatString, __arglist)
{
TestArgIterator(builder, bufferSize, formatString, new ArgIterator(__arglist));
}

private static bool AssertEqual(string lhs, string rhs)
{
if (lhs != rhs)
{
Console.WriteLine($"FAIL! \"{lhs}\" != \"{rhs}\"");
return false;
}
return true;
}

public static int Main()
{
var passed = true;
int arg1 = 10;
int arg2 = 20;
double arg3 = 12.5;

string expected = $"{arg1}, {arg2}, {arg3:F1}";

StringBuilder builder;

builder = new StringBuilder(30);
TestVarArgs(builder, (IntPtr)30, "%i, %i, %.1f", __arglist(arg1, arg2, arg3));
passed &= AssertEqual(builder.ToString(), expected);

builder = new StringBuilder(30);
TestArgIteratorWrapper(builder, (IntPtr)30, "%i, %i, %.1f", __arglist(arg1, arg2, arg3));
passed &= AssertEqual(builder.ToString(), expected);

return passed ? 100 : 101;
}
}
}
42 changes: 42 additions & 0 deletions tests/src/Interop/PInvoke/Varargs/VarargsTest.csproj
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<AssemblyName>VarargsTest</AssemblyName>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
<OutputType>exe</OutputType>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>$(DefineConstants);STATIC</DefineConstants>

<!-- Varargs/ArgIterator marshalling 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>
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
<Visible>False</Visible>
</CodeAnalysisDependentAssemblyPaths>
</ItemGroup>
<ItemGroup>
<Compile Include="*.cs" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj">
<Project>{c8c0dc74-fac4-45b1-81fe-70c4808366e0}</Project>
<Name>CoreCLRTestLibrary</Name>
</ProjectReference>
<ProjectReference Include="CMakeLists.txt"></ProjectReference>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>