Are [UnmanagedCallersOnly]
methods implicitly pinned?
#108752
-
I'm writing a Win32 async I/O method (one with a completion callback). I've managed to pack my We then take that Is anything necessary to avoid a GC hole with the I ask because I know normal delegates need For a simplistic overview, this is what we're doing: NativeOverlapped* lpOverlapped = overlapped.Pack(<data>);
delegate* unmanaged[Stdcall]<uint, uint, NativeOverlapped* void> lpOverlappedCompletionRoutine = &NativeCallback;
if (!ReadFileEx(..., lpOverlapped, lpOverlappedCompletionRoutine))
{
overlapped.Free();
// handle HRESULT
} [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])]
internal static void NativeCallback(uint dwErrorCode, uint dwNumberOfBytesTransferred, NativeOverlapped* lpOverlapped)
{
MyOverlapped overlapped = MyOverlapped.Unpack(lpOverlapped, out object?[] data);
// process result
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
The calling convention of delegate and corresponding unmanaged method are different. Thus, marshalling delegate into function pointer can require an extra thumb of code. When the delegate is instance method, it also needs to be kept alive for dispatching the target.
|
Beta Was this translation helpful? Give feedback.
-
From the blog post originally announcing the feature:
Like @huoyaoyuan mentioned, the one exception you might have to worry about is if your assembly is loaded into an unloadable assembly load context. If you try to call an Here is a small program that demonstrates how to do the cleanup: https://gist.github.com/AustinWise/92f48f2f4c1ce04795599822a7aced89 It calls the Windows function |
Beta Was this translation helpful? Give feedback.
From the blog post originally announcing the feature:
Like @huoyaoyuan mentioned, the one exception you might have to worry about is if your assembly is loaded into an unloadable assembly load context. If you try to call an
UnmanagedCallersOnly
function after the assembly that defines it has been unloaded, you will crash. You can use theAssemblyLoadContext.Unloading
event to clean up callbacks to prevent this crash.Here is a small program that demonstrates how to do the cleanup:
https://gist.github.com/AustinWise/92f48f2f4c1ce04795599822a7aced89
It calls the Windows function
RegisterWaitForSingleObject
…