1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
6 using System
.Runtime
.InteropServices
;
8 using System
.Collections
.Generic
;
14 [DllImport("libtest", CallingConvention
= CallingConvention
.Cdecl
)]
15 [return: MarshalAs(UnmanagedType
.LPUTF8Str
)]
16 public static extern string StringParameterInOut([In
, Out
][MarshalAs(UnmanagedType
.LPUTF8Str
)]string s
, int index
);
17 public static bool TestInOutStringParameter(string orgString
, int index
)
19 string passedString
= orgString
;
20 string expectedNativeString
= passedString
;
22 string nativeString
= StringParameterInOut(passedString
, index
);
23 if (!(nativeString
== expectedNativeString
))
25 Console
.WriteLine("StringParameterInOut: nativeString != expecedNativeString ");
31 [DllImport("libtest", CallingConvention
= CallingConvention
.Cdecl
)]
32 [return: MarshalAs(UnmanagedType
.LPUTF8Str
)]
33 public static extern string StringParameterOut([Out
][MarshalAs(UnmanagedType
.LPUTF8Str
)]string s
, int index
);
34 public static bool TestOutStringParameter(string orgString
, int index
)
36 string passedString
= orgString
;
37 string expecedNativeString
= passedString
;
38 string nativeString
= StringParameterInOut(passedString
, index
);
39 if (!(nativeString
== expecedNativeString
))
41 Console
.WriteLine("StringParameterInOut: nativeString != expecedNativeString ");
47 [DllImport("libtest", CallingConvention
= CallingConvention
.Cdecl
)]
48 public static extern void StringParameterRefOut([MarshalAs(UnmanagedType
.LPUTF8Str
)]out string s
, int index
);
49 public static bool TestStringPassByOut(string orgString
, int index
)
52 string expectedNative
= string.Empty
;
53 StringParameterRefOut(out expectedNative
, index
);
54 if (orgString
!= expectedNative
)
56 Console
.WriteLine ("TestStringPassByOut : expectedNative != outString");
62 [DllImport("libtest", CallingConvention
= CallingConvention
.Cdecl
)]
63 public static extern void StringParameterRef([MarshalAs(UnmanagedType
.LPUTF8Str
)]ref string s
, int index
);
64 public static bool TestStringPassByRef(string orgString
, int index
)
66 string orgCopy
= new string(orgString
.ToCharArray());
67 StringParameterRef(ref orgString
, index
);
68 if (orgString
!= orgCopy
)
70 Console
.WriteLine("TestStringPassByOut : string mismatch");
76 public static bool EmptyStringTest()
78 StringParameterInOut(string.Empty
, 0);
79 StringParameterOut(string.Empty
, 0);
85 class UTF8StringBuilderTests
87 [DllImport("libtest", CallingConvention
= CallingConvention
.Cdecl
)]
88 public static extern void StringBuilderParameterInOut([In
,Out
][MarshalAs(UnmanagedType
.LPUTF8Str
)]StringBuilder s
, int index
);
89 public static bool TestInOutStringBuilderParameter(string expectedString
, int index
)
91 StringBuilder nativeStrBuilder
= new StringBuilder(expectedString
);
93 StringBuilderParameterInOut(nativeStrBuilder
, index
);
95 if (!nativeStrBuilder
.ToString().Equals(expectedString
))
97 Console
.WriteLine($"TestInOutStringBuilderParameter: nativeString != expecedNativeString index={index} got={nativeStrBuilder} and expected={expectedString} ");
103 [DllImport("libtest", CallingConvention
= CallingConvention
.Cdecl
)]
104 public static extern void StringBuilderParameterOut([Out
][MarshalAs(UnmanagedType
.LPUTF8Str
)]StringBuilder s
, int index
);
105 public static bool TestOutStringBuilderParameter(string expectedString
, int index
)
107 // string builder capacity
108 StringBuilder nativeStringBuilder
= new StringBuilder(expectedString
.Length
);
110 StringBuilderParameterOut(nativeStringBuilder
, index
);
112 if (!nativeStringBuilder
.ToString().Equals(expectedString
))
114 Console
.WriteLine("TestOutStringBuilderParameter: string != expecedString ");
121 [DllImport("libtest", CallingConvention
= CallingConvention
.Cdecl
)]
122 [return: MarshalAs(UnmanagedType
.LPUTF8Str
,SizeConst
= 512)]
123 public static extern StringBuilder
StringBuilderParameterReturn(int index
);
124 public static bool TestReturnStringBuilder(string expectedReturn
, int index
)
126 StringBuilder nativeString
= StringBuilderParameterReturn(index
);
127 if (!expectedReturn
.Equals(nativeString
.ToString()))
129 Console
.WriteLine(string.Format( "TestReturnStringBuilder: nativeString {0} != expecedNativeString {1}",nativeString
.ToString(),expectedReturn
) );
136 // UTF8 string as struct field
137 class UTF8StructMarshalling
139 public struct Utf8Struct
141 [MarshalAs(UnmanagedType
.LPUTF8Str
)]
142 public string FirstName
;
146 [DllImport("libtest", CallingConvention
= CallingConvention
.Cdecl
)]
147 public static extern void TestStructWithUtf8Field(Utf8Struct utfStruct
);
148 public static bool TestUTF8StructMarshalling(string[] utf8Strings
)
150 Utf8Struct utf8Struct
= new Utf8Struct();
151 for (int i
= 0; i
< utf8Strings
.Length
; i
++)
153 utf8Struct
.FirstName
= utf8Strings
[i
];
154 utf8Struct
.index
= i
;
155 TestStructWithUtf8Field(utf8Struct
);
161 // UTF8 string as delegate parameter
162 class UTF8DelegateMarshalling
164 [UnmanagedFunctionPointer(CallingConvention
.Cdecl
)]
165 public delegate void DelegateUTF8Parameter([MarshalAs(UnmanagedType
.LPUTF8Str
)]string utf8String
, int index
);
167 [DllImport("libtest", CallingConvention
= CallingConvention
.Cdecl
)]
168 public static extern void Utf8DelegateAsParameter(DelegateUTF8Parameter param
);
171 public static bool TestUTF8DelegateMarshalling()
174 Utf8DelegateAsParameter(new DelegateUTF8Parameter(Utf8StringCallback
));
179 public static void Utf8StringCallback(string nativeString
, int index
)
181 if (string.CompareOrdinal(nativeString
, Test
.utf8Strings
[index
]) != 0)
183 Console
.WriteLine("Utf8StringCallback string do not match");
192 public static string[] utf8Strings
= {
194 "Sîne klâwen durh die wolken sint geslagen" ,
195 "काचं शक्नोम्यत्तुम् । नोपहिनस्ति माम्",
197 "ღმერთსი შემვედრე,შემვედრე, ნუთუ კვლა დამხსნას შემვედრე,სოფლისა შემვედრე, შემვედრე,შემვედრე,შემვედრე,შრომასა, ცეცხლს, წყალსა და მიწასა, ჰაერთა თანა მრომასა; მომცნეს ფრთენი და აღვფრინდე, მივჰხვდე მას ჩემსა ნდომასა, დღისით და ღამით ვჰხედვიდე მზისა ელვათა კრთომაასაშემვედრე,შემვედრე,",
198 "Τη γλώσσα μου έδωσαν ελληνική",
202 public static int Main(string[] args
)
204 // Test string as [In,Out] parameter
205 for (int i
= 0; i
< utf8Strings
.Length
; i
++)
206 if (!UTF8StringTests
.TestInOutStringParameter(utf8Strings
[i
], i
))
209 // Test string as [Out] parameter
210 for (int i
= 0; i
< utf8Strings
.Length
; i
++)
211 if (!UTF8StringTests
.TestOutStringParameter(utf8Strings
[i
], i
))
214 for (int i
= 0; i
< utf8Strings
.Length
- 1; i
++)
215 if (!UTF8StringTests
.TestStringPassByOut(utf8Strings
[i
], i
))
218 for (int i
= 0; i
< utf8Strings
.Length
- 1; i
++)
219 if (!UTF8StringTests
.TestStringPassByRef(utf8Strings
[i
], i
))
223 // Test StringBuilder as [In,Out] parameter
224 for (int i
= 0; i
< utf8Strings
.Length
- 1; i
++)
225 if (!UTF8StringBuilderTests
.TestInOutStringBuilderParameter(utf8Strings
[i
], i
))
229 // This requires support for [Out] in StringBuilder
231 // Test StringBuilder as [Out] parameter
232 for (int i
= 0; i
< utf8Strings
.Length
- 1; i
++){
233 if (!UTF8StringBuilderTests
.TestOutStringBuilderParameter(utf8Strings
[i
], i
))
239 // utf8 string as struct fields
240 if (!UTF8StructMarshalling
.TestUTF8StructMarshalling(utf8Strings
))
245 UTF8DelegateMarshalling
.TestUTF8DelegateMarshalling();
246 } catch (ExecutionEngineException
){
247 // Known issue on AOT - we do not AOT this yet.
251 // This requires special support for StringBuilder return values
252 // Test StringBuilder as return value
253 for (int i
= 0; i
< utf8Strings
.Length
- 1; i
++)
254 if (!UTF8StringBuilderTests
.TestReturnStringBuilder(utf8Strings
[i
], i
))
257 // String.Empty tests
258 if (!UTF8StringTests
.EmptyStringTest())