当我们不知道参数时如何调用过程或函数?

Jav*_*vid 5 delphi dll procedure function

我的应用程序必须提供从外部DLL调用不同函数和过程的能力.所以我们不知道参数的数量和类型.我该怎么做呢?

让我解释一下.我的应用程序是一个RAD工具,它有自己的脚本和语法...我想让用户使用任何 DLL文件并调用他们想要的任何函数或过程.我不能使用调用dll(LoadLibrary然后GetProcAddress)的简单方法,因为我不知道GetProcAddress引用的是什么类型(var Proc:procedure (A:??;B:??;...)).

Vil*_*nde 5

我在ZGameEditor项目的脚本功能中有一个Delphi实现,在下面的文件中搜索"TExpExternalFuncCall.Execute":

http://code.google.com/p/zgameeditor/source/browse/trunk/ZExpressions.pas

在Windows(x86和x64),Linux,Android(ARM)和OS X(x86)下测试和工作.处理stdcall和cdecl调用约定.

但是libFFI可能比我的实现更通用,所以我建议采用这种方法.


And*_*and 4

这是一个在我的机器上运行的简单示例,但我不是该主题的专家。

procedure TForm4.Button1Click(Sender: TObject);
var
  hmod: HMODULE;
  paddr: pointer;         
  c1, c2, ret: cardinal;
begin
  c1 := 400; //frequency
  c2 := 2000; // duration

  hmod := LoadLibrary('kernel32'); // Of course, the name of the DLL is taken from the script
  if hmod <> 0 then
    try
      paddr := GetProcAddress(hmod, 'Beep'); // ...as is the name of the exported function
      if paddr <> nil then
      begin
        // The script is told that this function requires two cardinals as
        // arguments. Let's call them c1 and c2. We will assume stdcall
        // calling convention. We will assume a 32-bit return value; this
        // we will store in ret.
        asm
          push c2
          push c1
          call [paddr]
          mov ret, eax
        end;
      end;
    finally
      FreeLibrary(hmod);
    end;
end;
Run Code Online (Sandbox Code Playgroud)

  • 您在这里提供的内容虽然对于“Beep”的特定情况是正确的,但实际上过于简单化了。在现实世界中,我们需要处理多种调用约定及其所有细节(堆栈上参数的顺序、使用的寄存器、谁清理堆栈、如何返回结果)。 (2认同)