FASM - Passing a String to a Delphi DLL
-
13-07-2021 - |
سؤال
I have a dll coded in Delphi XE2 with the following code:
procedure xMain(MSG:String);export;
begin
MessageBox(0,PWideChar(MSG),'Title',0);
end;
exports xMain;
Now, I am importing this function in a FASM application like so:
library dllfile, "testdll.dll"
import dllfile,\
xMain, "xMain"
And utilizing is as so:
section ".data" data readable writeable
szMSG db "Message from FASM application!",0
section ".code" code readable executable
invoke xMain,szMSG
But the resulting messagebox appears with distorted characters as so:
That is the exact result of the function call.
How do I go about solving this issue?
المحلول
Here are two working samples (using FASM 1.70.03 for Windows):
Ansi version,
dll:
library testdll;
uses
windows;
procedure xMain(MSG: PAnsiChar); export; stdcall;
begin
MessageBoxA(0, PAnsiChar(MSG), 'Title', 0);
end;
exports xMain;
begin
end.
exe:
format PE CONSOLE 4.0
entry start
include 'win32a.inc'
section '.code' code readable executable
start:
invoke xMain, szMSG
invoke ExitProcess, 0
section '.data' data readable writeable
szMSG db 'Message from FASM application!', 0
section '.idata' import data readable writeable
library kernel32, 'kernel32.dll',\
dllfile, 'testdll.dll'
include 'api\kernel32.inc'
import dllfile,\
xMain, 'xMain'
Unicode version,
dll:
library testdll;
uses
windows;
procedure xMain(MSG: PChar); export; stdcall;
begin
MessageBox(0, PChar(MSG), 'Title', 0);
end;
exports xMain;
begin
end.
exe:
format PE CONSOLE 4.0
entry start
include 'win32w.inc'
section '.code' code readable executable
start:
invoke xMain, szMSG
invoke ExitProcess, 0
section '.data' data readable writeable
szMSG du 'Message from FASM application!', 0
section '.idata' import data readable writeable
library kernel32, 'kernel32.dll',\
dllfile, 'testdll.dll'
include 'api\kernel32.inc'
import dllfile,\
xMain, 'xMain'
نصائح أخرى
Your output is what happens when you send ANSI text to a function that is expecting UTF-16 encoded text. From which I conclude that your FASM code is sending an ANSI payload to the DLL. And the DLL is compiled in a Unicode aware Delphi for which string
means UnicodeString
, Char
means WideChar
and so on.
You need to make the two sides match up. For example, by changing the Delphi code:
procedure xMain(Msg: PAnsiChar); stdcall;
begin
MessageBoxA(0, Msg, 'Title', 0);
end;
Some other points to note:
- You don't need
export
on the end of your function declaration. It is ignored by modern Delphi compilers. - Don't use Delphi's managed string across module boundaries. In any case on the FASM side you declared the parameter to be a null-terminated pointer to ANSI encoded character array. And that's
PAnsiChar
. - Your code uses the Delphi
register
calling convention. It's hard to believe that FASM uses that. I'd expectstdcall
and Sertac's answer backs that up
Are you sure your MSG argument should be a String
and not a PChar
?