【问题标题】:Variable required error (Delphi) - How to take the address of a procedure?Variable required error (Delphi) - 如何获取程序的地址?
【发布时间】:2019-06-26 17:22:52
【问题描述】:

在这里使用 Delphi 7。当我获取一个过程的地址(目的是将此方法地址作为回调发送到外部 C++ DLL)时,Delphi 7 编译器会报告Variable required。为什么?有无参数列表如何获取方法的地址?

这是显示编译器错误的简化代码。

// ...

type
  PTProcedureCallback = ^TProcedureCallback;
  TProcedureCallback = procedure() of object;

  // ...

  TTestCallback = class
    constructor Create();
    procedure MyCallback();
  end;

    //...

implementation
  constructor TTestCallback.Create();
  var
    pCallback: PTProcedureCallback;
  begin
    // Constructor
    inherited;

    // Test callback
    pCallback := @MyCallback;   // <- [Error] Variable required
  end;

  procedure TTestCallback.MyCallback();
  begin
    // Do something
  end;
end;

【问题讨论】:

  • 您不能将方法指针(类的方法)传递给 C++ DLL,因为它有一个隐含的 Self 引用与它一起传递,而 C++ DLL 无法理解。 procedure of object 表示它将具有 Self 引用。 (这里不是问题的答案,但它会节省你在未来试图弄清楚为什么一旦你弄清楚它就不起作用的时间。)

标签: delphi pointers


【解决方案1】:

您根本不需要PTProcedureCallback,因为TProcedureCallback 已经是一个指针类型。

constructor TTestCallback.Create();
var
  pCallback: TProcedureCallback;
begin
  // Constructor
  inherited;
  // Test callback
  pCallback := MyCallback;
end;

话虽如此,您不能将 procedure of object 用作 C/C++ 回调,除非 C/C++ 代码是专门用 C++Builder 编写的,并且实际上期望通过 @987654327 得到 procedure of object @ 编译器扩展。否则,您将无法使用 非静态 类方法作为回调。但是,如果回调允许您传入用户定义的值,则可以使用该值传入对象的 Self 指针,以便您的回调可以访问其非静态成员。

另外,您的 TProcedureCallback 使用 Delphi 的默认 register 调用约定(C++Builder 中的 __fastcall),非 C++Builder 编译器中不存在该约定。只有 cdeclstdcall 是可移植的调用约定。

【讨论】:

  • 谢谢雷米。我现在正忙着解决这个问题。但是,如果我只是按照您的建议更改代码,我仍然会收到相同的 Variable required 错误。我实际上是在尝试回答这个问题:stackoverflow.com/questions/56707554 其中另一个问题已被标记为重复。当我没有指定参数时,我可以让 C++ DLL 调用我的方法,但是当我尝试使用整数参数时,参数会变成乱码。 C++ DLL 正在 Visual Studio 中构建,我尝试了 __cdecl__stdcall 调用约定。
  • 然后尝试简单的pCallback := MyCallback; 代替(删除@)。
  • 看起来我的问题就像你在第二段中所说的那样:我试图提供一个 non-static 类方法作为 C/C++ 回调。当我将方法设为静态(将procedure TTestCallback.MyCallback 更改为procedure MyCallback)时,它开始工作。有很多东西要学...谢谢雷米!
猜你喜欢
  • 2016-02-17
  • 2022-08-22
  • 2014-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多