Delphi thiscall调用约定

Chr*_*isB 9 c++ delphi

我需要调用非静态C++成员函数

因此我需要使用thiscall调用约定.

Delphi不支持此调用约定.

所以在我可以调用任何成员函数之前,我必须手动推送堆栈中的参数.

  asm
    mov ecx, myClassPointer
  end;
Run Code Online (Sandbox Code Playgroud)

这工作正常,但我正在寻找一个更好的方法来做到这一点.

目前我在调用函数之前每次使用classpointer调用asm代码,这是不好的.

由于我不是Delphi专家,我想知道你是否可以声明自己的调用约定或自动调用那些thiscall类方法.

Dav*_*nan 5

您有以下选择:

  • 在asm中写入适配器以调用该函数.这是您当前的解决方案,正如您所知,这种方法很脆弱且很尴尬.
  • 编写一个提供互操作友好界面的C++适配器.

在我看来,后一种选择是正确的解决方案.C++代码不适合互操作.通过interop公开C++类是完全错误的.它对消费者提出了不合理的要求.合理的方法包括在Win32中找到的COM和普通C样式互操作.

编写一个适应性的C++ DLL,它使用不合理的C++类并公开一个合适的互操作友好接口.适配器是用C++编写的,因此能够使用C++代码.但随后它会导出界面的互操作友好变体,可以从任何工具链轻松调用.


小智 4

Delphi 的register调用约定使用寄存器来存储前三个参数。前两个是EAXEDX,它们在调用约定中未使用thiscall,可以设置为您喜欢的任何值。其中第三个寄存器是ECX

thiscall传递堆栈上的所有参数,并register传递堆栈上的剩余参数。和registerthiscall让被调用者清理堆栈上传递的参数。

因此,您可以做的是声明一个函数,并使用和register的虚拟参数。您仍然可以将其包装在不同的函数中以使其更易于调用,但至少现在可以声明包装函数。EAXEDXinline

thiscall但请注意,和之间参数压入堆栈的顺序不同register,因此您需要反转参数以匹配。