Skip to content

Commit a9bc1b7

Browse files
authored
Add custom marshaller tests for delegates (#62691)
1 parent fcaf311 commit a9bc1b7

File tree

6 files changed

+108
-1
lines changed

6 files changed

+108
-1
lines changed

src/tests/Interop/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ add_subdirectory(NativeLibrary/NativeLibraryToLoad)
5757
add_subdirectory(DllImportAttribute/DllImportPath)
5858
add_subdirectory(DllImportAttribute/ExactSpelling)
5959
add_subdirectory(ICustomMarshaler/ConflictingNames)
60+
add_subdirectory(ICustomMarshaler/Primitives)
6061
add_subdirectory(LayoutClass)
6162
add_subdirectory(PInvoke/DateTime)
6263
if(CLR_CMAKE_TARGET_WIN32)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
project (CustomMarshalersPrimitives)
2+
include_directories(${INC_PLATFORM_DIR})
3+
set(SOURCES ICustomMarshalerNative.cpp )
4+
5+
# add the executable
6+
add_library (CustomMarshalersPrimitives SHARED ${SOURCES})
7+
target_link_libraries(CustomMarshalersPrimitives ${LINK_LIBRARIES_ADDITIONAL})
8+
9+
# add the install targets
10+
install (TARGETS CustomMarshalersPrimitives DESTINATION bin)

src/tests/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.cs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,37 @@ public static void Parameter_CustomMarshalerProvided_CallsMethodsInCorrectOrderi
164164
"Called CleanUpNativeData"
165165
});
166166
Assert.Equal(expectedOrderingSecondCall, OrderTrackingCustomMarshaler.Events);
167+
168+
// GetInstance is only called once.
169+
string val3 = "7488";
170+
Assert.Equal(val3, OrderTrackingMethodRef(ref val3));
171+
IEnumerable<string> expectedOrderingThirdCall = expectedOrderingSecondCall.Concat(new string[]
172+
{
173+
"Called MarshalManagedToNative",
174+
"Called MarshalNativeToManaged",
175+
"Called CleanUpManagedData",
176+
"Called MarshalNativeToManaged",
177+
"Called CleanUpNativeData",
178+
});
179+
Assert.Equal(expectedOrderingThirdCall.Skip(7), OrderTrackingCustomMarshaler.Events.Skip(7));
180+
181+
OrderTrackingMethodOut(out var val4);
182+
Assert.Equal("2334", val4);
183+
IEnumerable<string> expectedOrderingForthCall = expectedOrderingThirdCall.Concat(new string[]
184+
{
185+
"Called MarshalNativeToManaged",
186+
});
187+
Assert.Equal(expectedOrderingForthCall.Skip(12), OrderTrackingCustomMarshaler.Events.Skip(12));
188+
189+
var val5 = OrderTrackingMethodDelegate(439, (x) => x.ToString());
190+
Assert.Equal("439", val5);
191+
IEnumerable<string> expectedOrderingFifthCall = expectedOrderingForthCall.Concat(new string[]
192+
{
193+
"Called MarshalManagedToNative",
194+
"Called CleanUpManagedData",
195+
"Called MarshalNativeToManaged",
196+
});
197+
Assert.Equal(expectedOrderingFifthCall.Skip(13), OrderTrackingCustomMarshaler.Events.Skip(13));
167198
}
168199

169200
// This should only be used *once*, as it uses static state.
@@ -201,7 +232,7 @@ public IntPtr MarshalManagedToNative(object ManagedObj)
201232
public object MarshalNativeToManaged(IntPtr pNativeData)
202233
{
203234
Events.Add("Called MarshalNativeToManaged");
204-
return pNativeData.ToInt32().ToString();
235+
return pNativeData.ToInt64().ToString();
205236
}
206237

207238
public static ICustomMarshaler GetInstance(string cookie)
@@ -216,6 +247,20 @@ public static ICustomMarshaler GetInstance(string cookie)
216247
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))]
217248
public static extern string OrderTrackingMethod([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))] string str);
218249

250+
[DllImport("CustomMarshalersPrimitives", EntryPoint = "NativeParseIntRef")]
251+
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))]
252+
public static extern string OrderTrackingMethodRef([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))] ref string str);
253+
254+
[DllImport("CustomMarshalersPrimitives", EntryPoint = "NativeParseIntOut")]
255+
public static extern void OrderTrackingMethodOut([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))] out string str);
256+
257+
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))]
258+
public delegate string TestDelegate(int val);
259+
260+
[DllImport("CustomMarshalersPrimitives", EntryPoint = "NativeParseIntDelegate")]
261+
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))]
262+
public static extern string OrderTrackingMethodDelegate(int val, TestDelegate dlg);
263+
219264
public static void CustomMarshaler_BothMarshalTypeRefAndMarshalTypeProvided_PicksMarshalType()
220265
{
221266
Assert.Equal(2, BothTypeRefAndTypeMethod("64001"));
@@ -613,6 +658,17 @@ public void CleanUpManagedData(object ManagedObj) { }
613658
[DllImport(LibcLibrary, EntryPoint = "atoi", CallingConvention = CallingConvention.Cdecl)]
614659
public static extern int DifferentCustomMarshalerType([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OuterCustomMarshaler))] string str);
615660

661+
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BoxedValueTypeCustomMarshaler))]
662+
public delegate string TestDelegateRef([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BoxedValueTypeCustomMarshaler))] ref int val);
663+
664+
[DllImport("CustomMarshalersPrimitives", EntryPoint = "NativeParseIntDelegateRef")]
665+
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BoxedValueTypeCustomMarshaler))]
666+
public static extern string CustomMarshallerWithDelegateRef(int val, TestDelegateRef dlg);
667+
668+
public static void DelegateParameter_MarshalerOnRefInt_ThrowsMarshalDirectiveException()
669+
{
670+
Assert.Throws<MarshalDirectiveException>(() => CustomMarshallerWithDelegateRef(84664, (ref int x) => x.ToString()));
671+
}
616672
public static int Main(String[] args)
617673
{
618674
try
@@ -643,6 +699,7 @@ public static int Main(String[] args)
643699
Parameter_CleanUpNativeDataMethodThrows_ThrowsActualException();
644700
Field_ParentIsStruct_ThrowsTypeLoadException();
645701
Parameter_DifferentCustomMarshalerType_MarshalsCorrectly();
702+
DelegateParameter_MarshalerOnRefInt_ThrowsMarshalDirectiveException();
646703
}
647704
catch (Exception e)
648705
{
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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+
4+
#include <stdlib.h>
5+
#include <xplatform.h>
6+
7+
using TestDelegate = LPCSTR(STDMETHODCALLTYPE*)(int);
8+
using TestDelegateRef = LPCSTR(STDMETHODCALLTYPE*)(int*);
9+
10+
extern "C" int DLL_EXPORT STDMETHODCALLTYPE NativeParseInt(LPCSTR str)
11+
{
12+
return atoi(str);
13+
}
14+
15+
extern "C" int DLL_EXPORT STDMETHODCALLTYPE NativeParseIntRef(LPCSTR* str)
16+
{
17+
return atoi(*str);
18+
}
19+
20+
extern "C" void DLL_EXPORT STDMETHODCALLTYPE NativeParseIntOut(int* outVal)
21+
{
22+
*outVal = 2334;
23+
}
24+
25+
extern "C" int DLL_EXPORT STDMETHODCALLTYPE NativeParseIntDelegate(int val, TestDelegate del)
26+
{
27+
return atoi(del(val));
28+
}
29+
30+
extern "C" int DLL_EXPORT STDMETHODCALLTYPE NativeParseIntDelegateRef(int val, TestDelegateRef del)
31+
{
32+
return atoi(del(&val));
33+
}

src/tests/Interop/ICustomMarshaler/Primitives/ICustomMarshaler_TargetUnix.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@
1010
<ItemGroup>
1111
<Compile Include="ICustomMarshaler.cs" />
1212
</ItemGroup>
13+
<ItemGroup>
14+
<ProjectReference Include="CMakeLists.txt" />
15+
</ItemGroup>
1316
</Project>

src/tests/Interop/ICustomMarshaler/Primitives/ICustomMarshaler_TargetWindows.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,7 @@
1111
<ItemGroup>
1212
<Compile Include="ICustomMarshaler.cs" />
1313
</ItemGroup>
14+
<ItemGroup>
15+
<ProjectReference Include="CMakeLists.txt" />
16+
</ItemGroup>
1417
</Project>

0 commit comments

Comments
 (0)