diff --git a/src/tests/Interop/StringMarshalling/UTF8/UTF8Test.cs b/src/tests/Interop/StringMarshalling/UTF8/UTF8Test.cs index 44decce077a698..3dfcd9efa2de86 100644 --- a/src/tests/Interop/StringMarshalling/UTF8/UTF8Test.cs +++ b/src/tests/Interop/StringMarshalling/UTF8/UTF8Test.cs @@ -7,281 +7,217 @@ using System.Collections.Generic; using Xunit; -// UTF8 -class UTF8StringTests +namespace StringMarshaling { - [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] - [return: MarshalAs(UnmanagedType.LPUTF8Str)] - public static extern string StringParameterInOut([In, Out][MarshalAs(UnmanagedType.LPUTF8Str)]string s, int index); - public static void TestInOutStringParameter(string orgString, int index) + [OuterLoop] + [ActiveIssue("https://github.com/dotnet/runtime/issues/91388", typeof(TestLibrary.PlatformDetection), nameof(TestLibrary.PlatformDetection.PlatformDoesNotSupportNativeTestAssets))] + public class UTF8Tests { - string passedString = orgString; - string expectedNativeString = passedString; + [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.LPUTF8Str)] + static extern string StringParameterInOut([In, Out][MarshalAs(UnmanagedType.LPUTF8Str)] string s, int index); + + [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.LPUTF8Str)] + static extern string StringParameterOut([Out][MarshalAs(UnmanagedType.LPUTF8Str)] string s, int index); + + [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] + static extern void StringParameterRefOut([MarshalAs(UnmanagedType.LPUTF8Str)] out string s, int index); + + [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool StringParameterRef([MarshalAs(UnmanagedType.LPUTF8Str)] ref string s, int index); + + [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool StringBuilderParameterInOut([In, Out][MarshalAs(UnmanagedType.LPUTF8Str)] StringBuilder s, int index); + + [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] + static extern void StringBuilderParameterOut([Out][MarshalAs(UnmanagedType.LPUTF8Str)] StringBuilder s, int index); + + [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.LPUTF8Str, SizeConst = 512)] + static extern StringBuilder StringBuilderParameterReturn(int index); + + [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool TestStructWithUtf8Field(Utf8Struct utfStruct); + + [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] + static extern void SetStringInStruct(ref Utf8Struct utfStruct, [MarshalAs(UnmanagedType.LPUTF8Str)] string str); + + [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] + static extern void Utf8DelegateAsParameter(DelegateUTF8Parameter param); - string nativeString = StringParameterInOut(passedString, index); - if (!(nativeString == expectedNativeString)) + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void DelegateUTF8Parameter([MarshalAs(UnmanagedType.LPUTF8Str)] string utf8String, int index); + + public struct Utf8Struct { - throw new Exception("StringParameterInOut: nativeString != expectedNativeString "); + [MarshalAs(UnmanagedType.LPUTF8Str)] + public string FirstName; + public int index; } - } - [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] - [return: MarshalAs(UnmanagedType.LPUTF8Str)] - public static extern string StringParameterOut([Out][MarshalAs(UnmanagedType.LPUTF8Str)]string s, int index); - public static void TestOutStringParameter(string orgString, int index) - { - string passedString = orgString; - string expectedNativeString = passedString; - string nativeString = StringParameterInOut(passedString, index); - if (!(nativeString == expectedNativeString)) + unsafe struct UnmanagedStruct { - throw new Exception("StringParameterInOut: nativeString != expectedNativeString "); + public fixed byte psz[8]; } - } - [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] - public static extern void StringParameterRefOut([MarshalAs(UnmanagedType.LPUTF8Str)]out string s, int index); - public static void TestStringPassByOut(string orgString, int index) - { - // out string - string expectedNative = string.Empty; - StringParameterRefOut(out expectedNative, index); - if (orgString != expectedNative) + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + struct ManagedStruct { - throw new Exception("TestStringPassByOut : expectedNative != outString"); + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] + public string str; } - } - [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] - public static extern void StringParameterRef([MarshalAs(UnmanagedType.LPUTF8Str)]ref string s, int index); - public static void TestStringPassByRef(string orgString, int index) - { - string orgCopy = new string(orgString.ToCharArray()); - StringParameterRef(ref orgString, index); - if (orgString != orgCopy) + public static readonly string[] Utf8Strings = + { + "Managed", + "S\u00EEne kl\u00E2wen durh die wolken sint geslagen", + "\u0915\u093E\u091A\u0902 \u0936\u0915\u094D\u0928\u094B\u092E\u094D\u092F\u0924\u094D\u0924\u0941\u092E\u094D \u0964 \u0928\u094B\u092A\u0939\u093F\u0928\u0938\u094D\u0924\u093F \u092E\u093E\u092E\u094D", + "\u6211\u80FD\u541E\u4E0B\u73BB\u7483\u800C\u4E0D\u4F24\u8EAB\u4F53", + "\u10E6\u10DB\u10D4\u10E0\u10D7\u10E1\u10D8 \u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,\u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4, \u10DC\u10E3\u10D7\u10E3 \u10D9\u10D5\u10DA\u10D0 \u10D3\u10D0\u10DB\u10EE\u10E1\u10DC\u10D0\u10E1 \u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,\u10E1\u10DD\u10E4\u10DA\u10D8\u10E1\u10D0 \u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4, \u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,\u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,\u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,\u10E8\u10E0\u10DD\u10DB\u10D0\u10E1\u10D0, \u10EA\u10D4\u10EA\u10EE\u10DA\u10E1, \u10EC\u10E7\u10D0\u10DA\u10E1\u10D0 \u10D3\u10D0 \u10DB\u10D8\u10EC\u10D0\u10E1\u10D0, \u10F0\u10D0\u10D4\u10E0\u10D7\u10D0 \u10D7\u10D0\u10DC\u10D0 \u10DB\u10E0\u10DD\u10DB\u10D0\u10E1\u10D0; \u10DB\u10DD\u10DB\u10EA\u10DC\u10D4\u10E1 \u10E4\u10E0\u10D7\u10D4\u10DC\u10D8 \u10D3\u10D0 \u10D0\u10E6\u10D5\u10E4\u10E0\u10D8\u10DC\u10D3\u10D4, \u10DB\u10D8\u10D5\u10F0\u10EE\u10D5\u10D3\u10D4 \u10DB\u10D0\u10E1 \u10E9\u10D4\u10DB\u10E1\u10D0 \u10DC\u10D3\u10DD\u10DB\u10D0\u10E1\u10D0, \u10D3\u10E6\u10D8\u10E1\u10D8\u10D7 \u10D3\u10D0 \u10E6\u10D0\u10DB\u10D8\u10D7 \u10D5\u10F0\u10EE\u10D4\u10D3\u10D5\u10D8\u10D3\u10D4 \u10DB\u10D6\u10D8\u10E1\u10D0 \u10D4\u10DA\u10D5\u10D0\u10D7\u10D0 \u10D9\u10E0\u10D7\u10DD\u10DB\u10D0\u10D0\u10E1\u10D0\u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,\u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,", + "\u03A4\u03B7 \u03B3\u03BB\u03CE\u03C3\u03C3\u03B1 \u03BC\u03BF\u03C5 \u03AD\u03B4\u03C9\u03C3\u03B1\u03BD \u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AE", + null, + }; + + public static IEnumerable Utf8StringsWithIndex() { - throw new Exception("TestStringPassByOut : string mismatch"); + for (int i = 0; i < Utf8Strings.Length; i++) + yield return [Utf8Strings[i], i]; } - } - public static void EmptyStringTest() - { - StringParameterInOut(string.Empty, 0); - StringParameterOut(string.Empty, 0); - } -} - -// UTF8 stringbuilder -class UTF8StringBuilderTests -{ - [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] - public static extern void StringBuilderParameterInOut([In, Out][MarshalAs(UnmanagedType.LPUTF8Str)]StringBuilder s, int index); - public static void TestInOutStringBuilderParameter(string expectedString, int index) - { - StringBuilder nativeStrBuilder = new StringBuilder(expectedString); - StringBuilderParameterInOut(nativeStrBuilder, index); - - if (!nativeStrBuilder.ToString().Equals(expectedString)) + public static IEnumerable NonNullUtf8StringsWithIndex() { - throw new Exception("TestInOutStringBuilderParameter: nativeString != expectedNativeString "); + for (int i = 0; i < Utf8Strings.Length - 1; i++) + yield return [Utf8Strings[i], i]; } - } - [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] - public static extern void StringBuilderParameterOut([Out][MarshalAs(UnmanagedType.LPUTF8Str)]StringBuilder s, int index); - public static void TestOutStringBuilderParameter(string expectedString, int index) - { - // string builder capacity - StringBuilder nativeStringBuilder = new StringBuilder(expectedString.Length); - StringBuilderParameterOut(nativeStringBuilder, index); - - if (!nativeStringBuilder.ToString().Equals(expectedString)) + [Theory] + [MemberData(nameof(Utf8StringsWithIndex))] + public static void TestInOutStringParameter(string orgString, int index) { - throw new Exception("TestOutStringBuilderParameter: string != expectedString "); + string nativeString = StringParameterInOut(orgString, index); + Assert.Equal(orgString, nativeString); } - } - - [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] - [return: MarshalAs(UnmanagedType.LPUTF8Str,SizeConst = 512)] - public static extern StringBuilder StringBuilderParameterReturn(int index); - public static void TestReturnStringBuilder(string expectedReturn, int index) - { - StringBuilder nativeString = StringBuilderParameterReturn(index); - if (!expectedReturn.Equals(nativeString.ToString())) + [Theory] + [MemberData(nameof(Utf8StringsWithIndex))] + public static void TestOutStringParameter(string orgString, int index) { - throw new Exception(string.Format( "TestReturnStringBuilder: nativeString {0} != expectedNativeString {1}",nativeString.ToString(),expectedReturn) ); + string nativeString = StringParameterOut(orgString, index); + Assert.Equal(orgString, nativeString); } - } -} - -// UTF8 string as struct field -class UTF8StructMarshalling -{ - public struct Utf8Struct - { - [MarshalAs(UnmanagedType.LPUTF8Str)] - public string FirstName; - public int index; - } - - unsafe struct UnmanagedStruct - { - public fixed byte psz[8]; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - struct ManagedStruct - { - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] - public string str; - } - - [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] - public static extern void TestStructWithUtf8Field(Utf8Struct utfStruct); - - [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] - public static extern void SetStringInStruct(ref Utf8Struct utfStruct, [MarshalAs(UnmanagedType.LPUTF8Str)] string str); - public static void TestUTF8StructMarshalling(string[] utf8Strings) - { - Utf8Struct utf8Struct = new Utf8Struct(); - for (int i = 0; i < utf8Strings.Length; i++) + [Theory] + [MemberData(nameof(NonNullUtf8StringsWithIndex))] + public static void TestStringPassByOut(string orgString, int index) { - utf8Struct.FirstName = utf8Strings[i]; - utf8Struct.index = i; - TestStructWithUtf8Field(utf8Struct); + StringParameterRefOut(out string result, index); + Assert.Equal(orgString, result); } - if (!OperatingSystem.IsWindows()) - CompareWithUTF8Encoding(); - - string testString = "StructTestString\uD83D\uDE00"; - - SetStringInStruct(ref utf8Struct, testString); - if (utf8Struct.FirstName != testString) + [Theory] + [MemberData(nameof(NonNullUtf8StringsWithIndex))] + public static void TestStringPassByRef(string orgString, int index) { - throw new Exception("Incorrect UTF8 string marshalled back from native to managed."); + string copy = new string(orgString.ToCharArray()); + Assert.True(StringParameterRef(ref orgString, index)); + Assert.Equal(copy, orgString); } - } - - unsafe static void CompareWithUTF8Encoding() - { - // Compare results with UTF8Encoding - UnmanagedStruct ums; - ums.psz[0] = 0xFF; - ums.psz[1] = (byte)'a'; - ums.psz[2] = (byte)'b'; - ums.psz[3] = (byte)'c'; - ums.psz[4] = (byte)'d'; - ums.psz[5] = 0; - - IntPtr ptr = (IntPtr)(&ums); - ManagedStruct ms = Marshal.PtrToStructure(ptr); - string actual = ms.str; - - UTF8Encoding uTF8Encoding = new UTF8Encoding(); - byte [] b = new byte[5]; - b[0] = 0xFF; - b[1] = (byte)'a'; - b[2] = (byte)'b'; - b[3] = (byte)'c'; - b[4] = (byte)'d'; - string expected = uTF8Encoding.GetString(b); - if (actual != expected) - { - Console.WriteLine("Actual:" + actual + " Length:" + actual.Length); - Console.WriteLine("Expected:" + expected + " Length:" + expected.Length); - throw new Exception("UTF8Encoding.GetString doesn't match with Utf8 String Marshaller result"); - } - } -} -// UTF8 string as delegate parameter -class UTF8DelegateMarshalling -{ - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void DelegateUTF8Parameter([MarshalAs(UnmanagedType.LPUTF8Str)]string utf8String, int index); - - - [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)] - public static extern void Utf8DelegateAsParameter(DelegateUTF8Parameter param); - - - public static void TestUTF8DelegateMarshalling() - { - Utf8DelegateAsParameter(new DelegateUTF8Parameter(Utf8StringCallback)); - } - - public static void Utf8StringCallback(string nativeString, int index) - { - if (string.CompareOrdinal(nativeString, Test.utf8Strings[index]) != 0) + [Theory] + [MemberData(nameof(NonNullUtf8StringsWithIndex))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/123529", typeof(TestLibrary.Utilities), nameof(TestLibrary.Utilities.IsNativeAot))] + public static void TestInOutStringBuilderParameter(string expectedString, int index) { - throw new Exception("Utf8StringCallback string do not match"); + var builder = new StringBuilder(expectedString); + Assert.True(StringBuilderParameterInOut(builder, index)); + Assert.Equal(expectedString, builder.ToString()); } - } -} - - -public class Test -{ - //test strings - public static string[] utf8Strings = { - "Managed", - "S\u00EEne kl\u00E2wen durh die wolken sint geslagen" , - "\u0915\u093E\u091A\u0902 \u0936\u0915\u094D\u0928\u094B\u092E\u094D\u092F\u0924\u094D\u0924\u0941\u092E\u094D \u0964 \u0928\u094B\u092A\u0939\u093F\u0928\u0938\u094D\u0924\u093F \u092E\u093E\u092E\u094D", - "\u6211\u80FD\u541E\u4E0B\u73BB\u7483\u800C\u4E0D\u4F24\u8EAB\u4F53", - "\u10E6\u10DB\u10D4\u10E0\u10D7\u10E1\u10D8 \u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,\u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4, \u10DC\u10E3\u10D7\u10E3 \u10D9\u10D5\u10DA\u10D0 \u10D3\u10D0\u10DB\u10EE\u10E1\u10DC\u10D0\u10E1 \u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,\u10E1\u10DD\u10E4\u10DA\u10D8\u10E1\u10D0 \u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4, \u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,\u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,\u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,\u10E8\u10E0\u10DD\u10DB\u10D0\u10E1\u10D0, \u10EA\u10D4\u10EA\u10EE\u10DA\u10E1, \u10EC\u10E7\u10D0\u10DA\u10E1\u10D0 \u10D3\u10D0 \u10DB\u10D8\u10EC\u10D0\u10E1\u10D0, \u10F0\u10D0\u10D4\u10E0\u10D7\u10D0 \u10D7\u10D0\u10DC\u10D0 \u10DB\u10E0\u10DD\u10DB\u10D0\u10E1\u10D0; \u10DB\u10DD\u10DB\u10EA\u10DC\u10D4\u10E1 \u10E4\u10E0\u10D7\u10D4\u10DC\u10D8 \u10D3\u10D0 \u10D0\u10E6\u10D5\u10E4\u10E0\u10D8\u10DC\u10D3\u10D4, \u10DB\u10D8\u10D5\u10F0\u10EE\u10D5\u10D3\u10D4 \u10DB\u10D0\u10E1 \u10E9\u10D4\u10DB\u10E1\u10D0 \u10DC\u10D3\u10DD\u10DB\u10D0\u10E1\u10D0, \u10D3\u10E6\u10D8\u10E1\u10D8\u10D7 \u10D3\u10D0 \u10E6\u10D0\u10DB\u10D8\u10D7 \u10D5\u10F0\u10EE\u10D4\u10D3\u10D5\u10D8\u10D3\u10D4 \u10DB\u10D6\u10D8\u10E1\u10D0 \u10D4\u10DA\u10D5\u10D0\u10D7\u10D0 \u10D9\u10E0\u10D7\u10DD\u10DB\u10D0\u10D0\u10E1\u10D0\u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,\u10E8\u10D4\u10DB\u10D5\u10D4\u10D3\u10E0\u10D4,", - "\u03A4\u03B7 \u03B3\u03BB\u03CE\u03C3\u03C3\u03B1 \u03BC\u03BF\u03C5 \u03AD\u03B4\u03C9\u03C3\u03B1\u03BD \u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AE", - null, - }; - - [Fact] - [OuterLoop] - [ActiveIssue("https://github.com/dotnet/runtime/issues/91388", typeof(TestLibrary.PlatformDetection), nameof(TestLibrary.PlatformDetection.PlatformDoesNotSupportNativeTestAssets))] - public static void TestEntryPoint() - { - // Test string as [In,Out] parameter - for (int i = 0; i < utf8Strings.Length; i++) - UTF8StringTests.TestInOutStringParameter(utf8Strings[i], i); - - // Test string as [Out] parameter - for (int i = 0; i < utf8Strings.Length; i++) - UTF8StringTests.TestOutStringParameter(utf8Strings[i], i); - for (int i = 0; i < utf8Strings.Length - 1; i++) - UTF8StringTests.TestStringPassByOut(utf8Strings[i], i); + [Theory] + [MemberData(nameof(NonNullUtf8StringsWithIndex))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/123529", typeof(TestLibrary.Utilities), nameof(TestLibrary.Utilities.IsNativeAot))] + public static void TestOutStringBuilderParameter(string expectedString, int index) + { + var builder = new StringBuilder(expectedString.Length); + StringBuilderParameterOut(builder, index); + Assert.Equal(expectedString, builder.ToString()); + } - for (int i = 0; i < utf8Strings.Length - 1; i++) - UTF8StringTests.TestStringPassByRef(utf8Strings[i], i); + [Theory] + [MemberData(nameof(NonNullUtf8StringsWithIndex))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/123529", typeof(TestLibrary.Utilities), nameof(TestLibrary.Utilities.IsNativeAot))] + public static void TestReturnStringBuilder(string expectedReturn, int index) + { + StringBuilder nativeString = StringBuilderParameterReturn(index); + Assert.Equal(expectedReturn, nativeString.ToString()); + } - // https://github.com/dotnet/runtime/issues/123529 - if (!TestLibrary.Utilities.IsNativeAot) + [Theory] + [MemberData(nameof(Utf8StringsWithIndex))] + public static void TestStructWithUtf8FieldParameter(string str, int index) { - // Test StringBuilder as [In,Out] parameter - for (int i = 0; i < utf8Strings.Length - 1; i++) - UTF8StringBuilderTests.TestInOutStringBuilderParameter(utf8Strings[i], i); + var utf8Struct = new Utf8Struct { FirstName = str, index = index }; + Assert.True(TestStructWithUtf8Field(utf8Struct)); + } - // Test StringBuilder as [Out] parameter - for (int i = 0; i < utf8Strings.Length - 1; i++) - UTF8StringBuilderTests.TestOutStringBuilderParameter(utf8Strings[i], i); + [Fact] + public static void TestSetStringInStruct() + { + var utf8Struct = new Utf8Struct(); + string testString = "StructTestString\uD83D\uDE00"; + SetStringInStruct(ref utf8Struct, testString); + Assert.Equal(testString, utf8Struct.FirstName); } - // utf8 string as struct fields - UTF8StructMarshalling.TestUTF8StructMarshalling(utf8Strings); + [Fact] + public static void TestUTF8DelegateMarshalling() + { + Utf8DelegateAsParameter(new DelegateUTF8Parameter(Utf8StringCallback)); + } - // delegate - UTF8DelegateMarshalling.TestUTF8DelegateMarshalling(); + [Fact] + public static void TestEmptyString() + { + Assert.Null(StringParameterInOut(string.Empty, 0)); + Assert.Null(StringParameterOut(string.Empty, 0)); + } - // https://github.com/dotnet/runtime/issues/123529 - if (!TestLibrary.Utilities.IsNativeAot) + [Fact] + public static unsafe void CompareWithUTF8Encoding() { - // Test StringBuilder as [Out] parameter - for (int i = 0; i < utf8Strings.Length - 1; i++) - UTF8StringBuilderTests.TestReturnStringBuilder(utf8Strings[i], i); + if (OperatingSystem.IsWindows()) + return; + + UnmanagedStruct ums; + ums.psz[0] = 0xFF; + ums.psz[1] = (byte)'a'; + ums.psz[2] = (byte)'b'; + ums.psz[3] = (byte)'c'; + ums.psz[4] = (byte)'d'; + ums.psz[5] = 0; + + IntPtr ptr = (IntPtr)(&ums); + ManagedStruct ms = Marshal.PtrToStructure(ptr); + string actual = ms.str; + + UTF8Encoding uTF8Encoding = new UTF8Encoding(); + byte[] b = new byte[5]; + b[0] = 0xFF; + b[1] = (byte)'a'; + b[2] = (byte)'b'; + b[3] = (byte)'c'; + b[4] = (byte)'d'; + string expected = uTF8Encoding.GetString(b); + Assert.Equal(expected, actual); } - // String.Empty tests - UTF8StringTests.EmptyStringTest(); + static void Utf8StringCallback(string nativeString, int index) + { + Assert.Equal(0, string.CompareOrdinal(nativeString, Utf8Strings[index])); + } } } diff --git a/src/tests/Interop/StringMarshalling/UTF8/UTF8TestNative.cpp b/src/tests/Interop/StringMarshalling/UTF8/UTF8TestNative.cpp index 11eb92075b7c24..0a535eba7138b4 100644 --- a/src/tests/Interop/StringMarshalling/UTF8/UTF8TestNative.cpp +++ b/src/tests/Interop/StringMarshalling/UTF8/UTF8TestNative.cpp @@ -43,7 +43,8 @@ char* utf16_to_utf8(const wchar_t *srcstring) if (!nc) { - throw; + CoreClrFree(pszUTF8); + return nullptr; } pszUTF8[nc] = '\0'; @@ -81,9 +82,9 @@ wchar_t* utf8_to_utf16(const char *utf8) if (!nc) { - throw; + CoreClrFree(wszTextUTF16); + return nullptr; } - //MultiByteToWideChar do not null terminate the string when cbMultiByte is not -1 wszTextUTF16[nc] = '\0'; return wszTextUTF16; } @@ -135,11 +136,11 @@ LPSTR build_return_string(const char* pReturn) } // Modify the string builder in place, managed side validates. -extern "C" DLL_EXPORT void __cdecl StringBuilderParameterInOut(/*[In,Out] StringBuilder*/ char *s, int index) +extern "C" DLL_EXPORT BOOL __cdecl StringBuilderParameterInOut(/*[In,Out] StringBuilder*/ char *s, int index) { // if string.empty if (s == 0 || *s == 0) - return; + return TRUE; char *pszTextutf8 = get_utf8_string(index); @@ -150,7 +151,8 @@ extern "C" DLL_EXPORT void __cdecl StringBuilderParameterInOut(/*[In,Out] String if (s[i] != pszTextutf8[i]) { printf("[in] managed string do not match native string\n"); - throw; + free_utf8_string(pszTextutf8); + return FALSE; } } @@ -161,6 +163,7 @@ extern "C" DLL_EXPORT void __cdecl StringBuilderParameterInOut(/*[In,Out] String } s[outLen] = '\0'; free_utf8_string(pszTextutf8); + return TRUE; } //out string builder @@ -209,7 +212,7 @@ typedef struct FieldWithUtf8 }FieldWithUtf8; //utf8 struct field -extern "C" DLL_EXPORT void __cdecl TestStructWithUtf8Field(struct FieldWithUtf8 fieldStruct) +extern "C" DLL_EXPORT BOOL __cdecl TestStructWithUtf8Field(struct FieldWithUtf8 fieldStruct) { char *pszManagedutf8 = fieldStruct.pFirst; int stringIndex = fieldStruct.index; @@ -217,7 +220,7 @@ extern "C" DLL_EXPORT void __cdecl TestStructWithUtf8Field(struct FieldWithUtf8 size_t outLen = 0; if (pszManagedutf8 == 0 || *pszManagedutf8 == 0) - return; + return TRUE; pszNative = get_utf8_string(stringIndex); outLen = strlen(pszNative); @@ -227,10 +230,12 @@ extern "C" DLL_EXPORT void __cdecl TestStructWithUtf8Field(struct FieldWithUtf8 if (pszNative[i] != pszManagedutf8[i]) { printf("Native and managed string do not match.\n"); - throw; + free_utf8_string(pszNative); + return FALSE; } } free_utf8_string(pszNative); + return TRUE; } extern "C" DLL_EXPORT void __cdecl SetStringInStruct(FieldWithUtf8* fieldStruct, char* str) @@ -255,7 +260,7 @@ extern "C" DLL_EXPORT void __cdecl StringParameterRefOut(/*out*/ char **s, int i } //c# ref -extern "C" DLL_EXPORT void __cdecl StringParameterRef(/*ref*/ char **s, int index) +extern "C" DLL_EXPORT BOOL __cdecl StringParameterRef(/*ref*/ char **s, int index) { char *pszTextutf8 = get_utf8_string(index); size_t strLength = strlen(pszTextutf8); @@ -266,7 +271,8 @@ extern "C" DLL_EXPORT void __cdecl StringParameterRef(/*ref*/ char **s, int inde if ((*s)[i] != pszTextutf8[i]) { printf("[in] managed string do not match native string\n"); - throw; + free_utf8_string(pszTextutf8); + return FALSE; } } @@ -279,6 +285,7 @@ extern "C" DLL_EXPORT void __cdecl StringParameterRef(/*ref*/ char **s, int inde memcpy(*s, pszTextutf8, strLength); (*s)[strLength] = '\0'; free_utf8_string(pszTextutf8); + return TRUE; } // delegate test