diff --git a/src/mono/mono/metadata/marshal-lightweight.c b/src/mono/mono/metadata/marshal-lightweight.c index 072ddf5e176a32..2b8c321fce6f97 100644 --- a/src/mono/mono/metadata/marshal-lightweight.c +++ b/src/mono/mono/metadata/marshal-lightweight.c @@ -2629,6 +2629,7 @@ emit_managed_wrapper_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_s case MONO_TYPE_SZARRAY: case MONO_TYPE_CLASS: case MONO_TYPE_VALUETYPE: + case MONO_TYPE_PTR: mono_emit_marshal (m, i, invoke_sig->params [i], mspecs [i + 1], tmp_locals [i], NULL, MARSHAL_ACTION_MANAGED_CONV_OUT); break; default: diff --git a/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointer.cs b/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointer.cs index 34e075ad783e14..eff4068526eb16 100644 --- a/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointer.cs +++ b/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointer.cs @@ -13,6 +13,9 @@ static class FunctionPointerNative [DllImport(nameof(FunctionPointerNative))] public static extern bool CheckFcnPtr(IntPtr fcnptr); + + [DllImport(nameof(FunctionPointerNative))] + static unsafe extern void FillOutPtr(IntPtr* p); } delegate void VoidDelegate(); @@ -56,12 +59,34 @@ void VoidVoidMethod() } } + + [DllImport(nameof(FunctionPointerNative))] + static unsafe extern void FillOutPtr(IntPtr* p); + + private unsafe delegate void DelegateToFillOutPtr([Out] IntPtr* p); + + public static void RunGetDelForOutPtrTest() + { + Console.WriteLine($"Running {nameof(RunGetDelForOutPtrTest)}..."); + IntPtr outVar = 0; + int expectedValue = 60; + unsafe + { + DelegateToFillOutPtr d = new DelegateToFillOutPtr(FillOutPtr); + IntPtr ptr = Marshal.GetFunctionPointerForDelegate(d); + DelegateToFillOutPtr OutPtrDelegate = Marshal.GetDelegateForFunctionPointer(ptr); + OutPtrDelegate(&outVar); + } + Assert.Equal(expectedValue, outVar); + } + public static int Main() { try { RunGetDelForFcnPtrTest(); RunGetFcnPtrSingleMulticastTest(); + RunGetDelForOutPtrTest(); } catch (Exception e) { diff --git a/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointerNative.cpp b/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointerNative.cpp index 378a4180399a3f..9056f9af2ae72b 100644 --- a/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointerNative.cpp +++ b/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointerNative.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace { @@ -29,3 +30,8 @@ extern "C" DLL_EXPORT bool CheckFcnPtr(bool(STDMETHODCALLTYPE *fcnptr)(long long return fcnptr(999999999999); } } + +extern "C" DLL_EXPORT void FillOutPtr(intptr_t *p) +{ + *p = 60; +} diff --git a/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPtrTest.csproj b/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPtrTest.csproj index 38d1a61bba72a9..a69510fb96bc15 100644 --- a/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPtrTest.csproj +++ b/src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPtrTest.csproj @@ -1,6 +1,7 @@ Exe + true