Variable required error (Delphi) - How to take the address of a procedure?

Viewed 409

Using Delphi 7 here. When I take the address of a procedure (with the purpose of sending this method address to an external C++ DLL as a callback) the Delphi 7 compiler reports Variable required. Why? How do you take the address of a method with or without a parameter list?

Here's my simplified code which shows the compiler error.

// ...

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;
1 Answers

You don't need PTProcedureCallback at all, as TProcedureCallback is already a pointer type.

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

That being said, you can't use a procedure of object as a C/C++ callback, unless the C/C++ code was written in C++Builder specifically, and is actually expecting a procedure of object via the __closure compiler extension. If not, you will not be able to use a non-static class method as the callback. However, if the callback allows you to pass in a user-defined value, you can use that to pass in your object's Self pointer so your callback can access its non-static members.

Also, your TProcedureCallback is using Delphi's default register calling convention (__fastcall in C++Builder), which does not exist in non-C++Builder compilers. Only cdecl and stdcall are portable calling conventions.

Related