I ran into some unexpected behavior when playing around with native AOT in .NET 7 on Windows. It appears that if I export a method using the same name as a method I import from another native library, then trying to call the latter results in invoking the former. I realize sounds feels like a ridiculous conclusion to come to, but I'm not sure how else to interpret what I'm seeing.
I wanted to create a native library that simply exposes a CreateFileW
method, and then forwards that onto the read CreateFileW
method in kernel32.dll
. So I created this class library with native AOT enabled and published it:
[DllImport("kernel32.dll", EntryPoint = "CreateFileW")]
public static extern IntPtr RealCreateFile(
IntPtr filename,
uint access,
uint share,
IntPtr securityAttributes,
uint creationDisposition,
uint flagsAndAttributes,
IntPtr templateFile);
[UnmanagedCallersOnly(EntryPoint = "CreateFileW")]
public static IntPtr MyCreateFile(
IntPtr lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile)
{
Console.Out.WriteLine("Calling CreateFileW");
return RealCreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}
And then created this console app to consume it:
[DllImport("NativeClassTest.dll", EntryPoint = "CreateFileW")]
public static extern IntPtr MyCreateFile(
string filename,
uint access,
uint share,
IntPtr securityAttributes,
uint creationDisposition,
uint flagsAndAttributes,
IntPtr templateFile);
static void Main(string[] args)
{
var handle = MyCreateFile(@"C:\temp\test.txt", 1, 0, IntPtr.Zero, 3, 128, IntPtr.Zero);
}
Running this app will print Calling CreateFileW
repeatedly until a stack overflow occurs. If I change the name of my exported method (along with the import in my console app) then everything works fine.
Any searching I've done around DllImport
and stack overflows ends up being about marshalling problems, but if changing the name fixes the issue then it doesn't seem likely to be related.
I also haven't been able to figure out how to actually debug the AOT compiled library to help me better diagnose what's going on.
So my question is, is this known or expected behavior? How exactly does DllImport
work and am I using it wrong?