Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions xml/System.Runtime.InteropServices/Marshal.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4079,7 +4079,16 @@ The code retrieves a reference to an instance of Microsoft Word successfully. Ho
## Remarks
The delegate `d` is converted to a function pointer that can be passed to unmanaged code using [the default platform calling convention](/dotnet/standard/native-interop/calling-conventions#platform-default-calling-convention). You can set the calling convention by applying the <xref:System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute> to the delegate.

You must manually keep the delegate from being collected by the garbage collector from managed code. The garbage collector does not track references to unmanaged code.
You must manually keep the delegate from being collected by the garbage collector from managed code. The garbage collector does not track references to unmanaged code. Use <xref:System.GC.KeepAlive%2A> to prevent the delegate from being collected before the native call completes:

```csharp
var callback = new MyNativeCallback(MyManagedMethod);
IntPtr fnPtr = Marshal.GetFunctionPointerForDelegate(callback);
NativeMethod(fnPtr);
GC.KeepAlive(callback); // Prevent collection — fnPtr does not root the delegate.
```

If native code stores the function pointer beyond the duration of the call, root the delegate for its entire lifetime — for example, by storing it in a `static` field.

This API is unsupported in environments that don't support dynamic entry-point allocation, such as `ProcessDynamicCodePolicy` on Windows, `execmem off` in SELinux, and WebAssembly.

Expand Down Expand Up @@ -4155,7 +4164,16 @@ The code retrieves a reference to an instance of Microsoft Word successfully. Ho
## Remarks
The delegate `d` is converted to a function pointer that can be passed to unmanaged code by using [the default platform calling convention](/dotnet/standard/native-interop/calling-conventions#platform-default-calling-convention). You can set the calling convention by applying the <xref:System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute> to the delegate.

You must manually keep the delegate from being collected by the garbage collector from managed code. The garbage collector does not track references to unmanaged code.
You must manually keep the delegate from being collected by the garbage collector from managed code. The garbage collector does not track references to unmanaged code. Use <xref:System.GC.KeepAlive%2A> to prevent the delegate from being collected before the native call completes:

```csharp
var callback = new MyNativeCallback(MyManagedMethod);
IntPtr fnPtr = Marshal.GetFunctionPointerForDelegate(callback);
NativeMethod(fnPtr);
GC.KeepAlive(callback); // Prevent collection — fnPtr does not root the delegate.
```

If native code stores the function pointer beyond the duration of the call, root the delegate for its entire lifetime — for example, by storing it in a `static` field.

This API is unsupported in environments that don't support dynamic entry-point allocation, such as `ProcessDynamicCodePolicy` on Windows, `execmem off` in SELinux, and WebAssembly.

Expand Down