I'm trying to call a very simple Assembly procedure from C# to get something returned from it.
Here's the C# code:
class Program
{
static void Main(string[] args)
{
ulong test = Start();
Console.WriteLine(test);
}
[DllImport(@"C:\dev\masm\basic.dll")]
private static extern ulong Start();
}
Here's the Assembly (MASM) code:
.code
Start proc
mov rax, 1
ret
Start endp
end
I assemble and link from the console with the following command:
ml64 basic.asm /link /subsystem:console /entry:Start /out:basic.dll /dll /machine:x64
What's really interesting is that I'm able to successfully call a simple Assembly procedure that prints "Hello, World!" but doesn't return anything. However, when I try to call this procedure, even though I do specify an entry point in the DLL, I still get this error:
System.EntryPointNotFoundException: 'Unable to find an entry point named 'Start' in DLL 'C:\dev\masm\basic.dll'.'
I'm most likely missing something, but I can't figure it out.
CodePudding user response:
You were so close! You need to mark the procedure as an export.
.code
Start proc export
mov rax, 1
ret
Start endp
end
Console.WriteLine(test);
now prints 1
.
You can verify that the Start
procedure is exported by using a dev console and running DUMPBIN /HEADERS <DLL>
and seeing it in the export section
File Type: DLL
Section contains the following exports for basic.dll
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00001000 Start
Summary
1000 .rdata
1000 .text
An aside: the error you were getting
System.EntryPointNotFoundException: 'Unable to find an entry point named 'Start' in DLL 'C:\dev\masm\basic.dll'.'
doesn't actually have to do with the entry point of the dll (often called Main) but it's a PInvoke term that basically means "Hey, we couldn't find that exported "Start" method you told us to look for."