我有一个用 Visual C++ 2012 编写的程序,我试图调用一个用 Delphi 编写的函数(我没有源代码)。这是 Visual C++ 中的代码:
int (_fastcall *test)(void*) = (int(_fastcall *)(void*))0x00489A7D;
test((void *)0x12345678);
但在编译后的代码中它实际上是:
.text:1000113B mov eax, 489A7Dh
.text:10001140 mov ecx, 12345678h
.text:10001145 call eax
我要排除的是:
.text:1000113B mov ebx, 489A7Dh
.text:10001140 mov eax, 12345678h
.text:10001145 call ebx
我知道“fastcall”使用 EAX、ECX、EDX 作为参数,但我不知道为什么 Visual C++ 编译器使用 EAX 作为入口点。 EAX不应该是第一个参数(12345678h)吗?
我试图在汇编代码中调用 delphi 函数并且它有效,但我真的很想知道如何在不使用汇编代码的情况下做到这一点。
那么是否可以让 Visual C++ 编译器生成我所异常(exception)的代码?如果是,该怎么做?
最佳答案
德尔福的register x86 上的调用约定,也称为 Borland fastcall,使用 EAX, EDX and ECX registers , 以该顺序。
但是,Microsoft 的 fastcall 调用约定使用不同的寄存器。它根本不使用 EAX。相反,它使用 ECX 和 EDX 寄存器作为前两个参数,如 described by the documentation .
因此,有了这些信息,您可能会编写一些汇编程序,通过将参数移入 EAX
寄存器,从 C++ 调用 Delphi register
函数。然而,让 Delphi 编译器来做这件事会容易得多。特别是当我想象你的真正问题涉及多个函数和不止一个参数时。
我建议您编写一些 Pascal 代码以适应 stdcall
和 register
。
function FuncRegister(param: Pointer): Integer; register; external '...';
function FuncStdcall(param: Pointer): Integer; stdcall;
begin
Result := FuncRegister(param);
end;
exports
FuncStdcall;
然后您可以从您的 C++ 代码调用 FuncStdcall
并让 Delphi 编译器处理参数传递。
关于c++ - 如何使用 Visual C++ 中的 Delphi 寄存器调用约定调用函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15341954/