2

我有一个用 Delphi XE2 编码的 dll,代码如下:

procedure xMain(MSG:String);export;
begin
  MessageBox(0,PWideChar(MSG),'Title',0);
end;

exports xMain;

现在,我在 FASM 应用程序中导入这个函数,如下所示:

library  dllfile, "testdll.dll"

import   dllfile,\
         xMain,   "xMain"

使用方式如下:

section ".data" data readable writeable

szMSG     db "Message from FASM application!",0

section ".code" code readable executable

invoke    xMain,szMSG

但是生成的消息框出现扭曲的字符,如下所示:

在此处输入图像描述

这是函数调用的确切结果。

我该如何解决这个问题?

4

3 回答 3

6

您的输出是当您将 ANSI 文本发送到需要 UTF-16 编码文本的函数时发生的情况。我从中得出结论,您的 FASM 代码正在向 DLL 发送 ANSI 有效负载。并且 DLL 是在一个 Unicode 感知的 Delphi 中编译的,这string意味着UnicodeStringChar手段WideChar等等。

您需要使两侧匹配。例如,通过更改 Delphi 代码:

procedure xMain(Msg: PAnsiChar); stdcall;
begin
  MessageBoxA(0, Msg, 'Title', 0);
end;

其他一些需要注意的点:

  1. 您不需要export在函数声明的末尾。现代 Delphi 编译器忽略了它。
  2. 不要跨模块边界使用 Delphi 的托管字符串。在任何情况下,在 FASM 方面,您都将参数声明为指向 ANSI 编码字符数组的空终止指针。那就是PAnsiChar
  3. 您的代码使用 Delphiregister调用约定。很难相信 FASM 会使用它。我希望stdcall和 Sertac 的回答支持这一点
于 2012-10-23T13:41:18.650 回答
6

以下是两个工作示例(使用 FASM 1.70.03 for Windows):

Ansi版本,
dll:

library testdll;

uses
  windows;

procedure xMain(MSG: PAnsiChar); export; stdcall;
begin
  MessageBoxA(0, PAnsiChar(MSG), 'Title', 0);
end;

exports xMain;

begin
end.

可执行程序:

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 版本,
dll:

library testdll;

uses
  windows;

procedure xMain(MSG: PChar); export; stdcall;
begin
  MessageBox(0, PChar(MSG), 'Title', 0);
end;

exports xMain;

begin
end.

可执行程序:

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'
于 2012-10-29T20:54:41.753 回答
1

您确定您的 MSG 参数应该是 aString而不是 aPChar吗?

于 2012-10-22T18:00:53.317 回答