Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2015-06

How to use a static method as procedure variable?

5 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

silvioprog

Hello,

Consider the following sample:

=== begin code ===

type
  TMyProc = procedure(ABytes: array of Byte; out AOutput: AnsiString);
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private class var
    FMyProc: TMyProc;
  public
    class constructor Create;
    class procedure DoMyProc(ABytes: array of Byte; out AOutput:
AnsiString); overload; static;
    class property MyProc: TMyProc read FMyProc write FMyProc;
  end;
var
  Form1: TForm1;
implementation
{$R *.lfm}
procedure TForm1.Button1Click(Sender: TObject);
var
  S: AnsiString;
begin
  MyProc([65, 66, 67], S);
  ShowMessage(string(S));
end;
class constructor TForm1.Create;
begin
  FMyProc := @DoMyProc;
end;
class procedure TForm1.DoMyProc(ABytes: array of Byte; out AOutput:
AnsiString);
begin
  SetLength(AOutput, Length(ABytes));
  Move(ABytes[0], AOutput[1], Length(ABytes));
end;

=== end code ===

The code above compiles fine in Delphi (tested in XE 7), but in FPC I got the following compiling error:

Unit1.pas(46,14) Error: Incompatible types: got "<class method type of procedure({Open} Array Of Byte;out AnsiString) of object;Register>" expected "<procedure variable type of procedure({Open} Array Of Byte;out AnsiString);Register>".

Is this a bug or I need to enable some switch?

Thank you!

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Jonas Maebe
to silvioprog
silvioprog wrote 9 lines
The code above compiles fine in Delphi (tested in XE 7), but in FPC I got the following compiling error: Unit1.pas(46,14) Error: Incompatible types: got "<class method type of procedure({Open} Array Of Byte;out AnsiString) of object;Register>" expected "<procedure variable type of procedure({Open} Array Of Byte;out AnsiString);Register>". Is this a bug or I need to enable some switch?

FPC currently only supports that in Delphi mode:
http://bugs.freepascal.org/view.php?id=27414

Jonas

Reply by email

silvioprog
to Jonas Maebe
Jonas Maebe wrote 15 lines
On 30/06/15 20:54, silvioprog wrote: > The code above compiles fine in Delphi (tested in XE 7), but in FPC I > got the following compiling error: > > Unit1.pas(46,14) Error: Incompatible types: got "<class method type of > procedure({Open} Array Of Byte;out AnsiString) of object;Register>" > expected "<procedure variable type of procedure({Open} Array Of Byte;out > AnsiString);Register>". > > Is this a bug or I need to enable some switch? FPC currently only supports that in Delphi mode: http://bugs.freepascal.org/view.php?id=27414 Jonas

Hm... my unit (+- 500 lines) is implemented in mode objfpc, so if I change it to mode delphi I'll get several sintax erros.

It seems that the only way to fix that is using an usual procedure instead of a static method. =/

Plans to fix it for mode objfpc or it won't be solved?

Thanks!

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Ewald
to silvioprog: Consider the following sample: === begin code === type TMyProc = procedure(ABytes: array…
silvioprog wrote 7 lines
The code above compiles fine in Delphi (tested in XE 7), but in FPC I got the following compiling error: Unit1.pas(46,14) Error: Incompatible types: got "<class method type of procedure({Open} Array Of Byte;out AnsiString) of object;Register>" expected "<procedure variable type of procedure({Open} Array Of Byte;out AnsiString);Register>". Is this a bug or I need to enable some switch?

Back in 2012 I had a similar issue. Original message can be found here: http://lists.freepascal.org/pipermail/fpc-pascal/2012-December/035921.html

I fixed it by declaring a type that includes the hidden parameter mentioned in that thread, so in your case:

    Type
		TMyProc = procedure(aClassType: TClass; ABytes: array of Byte; out AOutput: AnsiString);
the invocation then becomes
	FMyProc(ClassType, [65, 66, 67], S);
instead of
	FMyProc([65, 66, 67], S);
And, of course, the assignment to FMyProc becomes more verbose and less type-safe:
	FMyProc := TMyProc(Pointer(@DoMyProc));

NOTE: This is a hack. It is not documented anywhere, but i have used this approach since late 2012 without any problems so far. Better be careful and write a small sanity test that checks correct operation every time you use a new compiler.

Ewald

Reply by email

silvioprog
to Ewald
Ewald wrote 40 lines
On 30 Jun 2015, at 20:54, silvioprog wrote: The code above compiles fine in Delphi (tested in XE 7), but in FPC I got the following compiling error: Unit1.pas(46,14) Error: Incompatible types: got "<class method type of procedure({Open} Array Of Byte;out AnsiString) of object;Register>" expected "<procedure variable type of procedure({Open} Array Of Byte;out AnsiString);Register>". Is this a bug or I need to enable some switch? Back in 2012 I had a similar issue. Original message can be found here: http://lists.freepascal.org/pipermail/fpc-pascal/2012-December/035921.html I fixed it by declaring a type that includes the hidden parameter mentioned in that thread, so in your case: Type TMyProc = procedure(aClassType: TClass; ABytes: array of Byte; out AOutput: AnsiString); the invocation then becomes FMyProc(ClassType, [65, 66, 67], S); instead of FMyProc([65, 66, 67], S); And, of course, the assignment to FMyProc becomes more verbose and less type-safe: FMyProc := TMyProc(Pointer(@DoMyProc)); NOTE: This is a hack. It is not documented anywhere, but i have used this approach since late 2012 without any problems so far. Better be careful and write a small sanity test that checks correct operation every time you use a new compiler.

Very nice, I'll try that, thank you! =)

Silvio Clécio My public projects - github.com/silvioprog

Reply by email