以下代码(仅用于演示问题)构建并在Delphi 2010中工作.在Delphi 2009中,编译器失败并显示“E2035实际参数不足”.
program Project50; {$APPTYPE CONSOLE} uses SysUtils; type TMyProc = reference to procedure(param: integer); var a: TProc; b: TMyProc; begin b := procedure (param: integer) begin end; a := TProc(b); // <-- [DCC Error] Project50.dpr(19): E2035 Not enough actual parameters end.
我发现只有一个非常难看的黑客来解决这个问题(a:TProc绝对b).有没有人知道这个编译器缺陷的更好的解决方法?
[TProc字段实际上隐藏在可以存储各种’可执行’代码的记录中 – TProcedure,TMethod和TProc. Casting用于将特定的匿名proc存储到此字段中.]
解决方法
我发现了一个黑客#2:
program Project1; {$APPTYPE CONSOLE} uses SysUtils; type TMyProc = reference to procedure(param: integer); var a: TProc; b: TMyProc; begin b := procedure (param: integer) begin Writeln('asdf'); end; PPointer(@a)^ := PPointer(@b)^; a; readln; end.
我怀疑你想通过将TMyProc(带param参数)分配给TProc(没有参数)来实现什么?
更新:一个hack#3(应该增加ref计数器,这个想法是从System._IntfCopy中窃取的):
procedure AnonCopy(var Dest; const Source); var P: Pointer; begin P:= Pointer(Dest); if Pointer(Source) <> nil then IInterface(Source)._AddRef; Pointer(Dest):= Pointer(Source); if P <> nil then IInterface(P)._Release; end; var a: TProc; b: TMyProc; begin b := procedure (param: integer) begin Writeln('asdf'); end; AnonCopy(a,b); // PPointer(@a)^ := PPointer(@b)^; a; readln; end.