A static library for NativeAOT projects, providing a native DllMain implementation that safely invokes a managed entrypoint after the Windows loader lock is released.
This library is necessary because the dotnet runtime initialization code does not meet the restrictions imposed by the Windows loader lock, making it impossible to implement DllMain directly in managed code.
NOTE: This functionality is only enabled when targeting win-x64 or win-x86.
- Reference the NativeDllMain NuGet package in your project.
- Add the following method to your project:
[UnmanagedCallersOnly(EntryPoint = "DllProcessAttach")]
public static void Main(nint hModule) // can be named anything you want as long as the unmanaged symbol is set to be "DllProcessAttach"
{
/*
Your entrypoint code here
*/
}Now, when your DLL is loaded, CreateThread is used to spawn a new thread for your managed entrypoint, which will be suspended until after the loader lock is released.
If an application queues an APC before the thread begins running, the thread begins by calling the APC function.
For a DLL that is loaded via the Import Address Table (IAT), such as a proxy DLL, DllMain is called before the main thread begins execution. Therefore it's recommended to use QueueUserAPC to call your managed entrypoint, instead of CreateThread, which prevents a race condition between the main thread and your managed entrypoint.
To enable this behaviour, add the following to a <PropertyGroup> in your csproj:
<DllMainUseQueueUserApc>true</DllMainUseQueueUserApc>NOTE: If your DLL is loaded via LoadLibrary or similar, you should continue to use CreateThread (the default behaviour), otherwise your managed entrypoint may never be called.
Essentially just replicate the CI instructions.
This project is subject to the terms of the Mozilla Public License, v. 2.0.