为什么我不能改变方法的指针?

时间:2015-04-10 18:12:15

标签: delphi pointers

我正在尝试更改TNotifyEvent的值,与使用指向其值的指针的整数相同。但是,当我尝试对TNotifyEvent这样做时,我得到一个异常(访问冲突)。我怎么能这样做?

我的目标是改变外部变量的值。这是一个代码,在这里解释我得到错误:

procedure TForm11.Button3Click(Sender: TObject);
var
  LInteger: integer;
  LPinteger: ^Integer;

  LPNotify: ^TNotifyEvent;
  LNotify: TNotifyEvent;
begin
  LInteger := 10;
  LPinteger := @LInteger;
  LPinteger^ := 20; //It's ok, it make both variables with the same value
  Caption := Format('Pointer: %d | Value: %d', [LPinteger^, LInteger]);

  LNotify := Button3Click;
  LPNotify := @LNotify;
  LPNotify^ := nil; //Here I get the error

  Caption := Format('Pointer: %d | Value: %d', [Integer(LPNotify), Integer(@LNotify)]);
end;

韩国社交协会

1 个答案:

答案 0 :(得分:3)

对于程序类型的变量,@运算符有不同的处理方式。 documentation说:

  

在某些情况下,不太清楚程序变量应该如何   被解释。请考虑以下声明:

if F = MyFunction then ...;
     

在这种情况下,F的出现导致函数调用;该   编译器调用F指向的函数,然后调用该函数   MyFunction,然后比较结果。规则是每当一个   程序变量出现在表达式中,它代表一个调用   参考程序或功能。在F引用的情况下   一个过程(它不会返回一个值),或者F引用一个过程   需要参数的函数,前一个语句导致一个   编译错误。比较F的程序值   MyFunction,使用:

if @F = @MyFunction then ...;
     

@F将F转换为包含一个的无类型指针变量   地址和@MyFunction返回MyFunction的地址。

     

获取程序变量的内存地址(而不是   存储在其中的地址),使用@@。例如,@@ F返回地址   F。

这是你的情景。而不是

LPNotify := @LNotify;

你需要

LPNotify := @@LNotify;

如果使用启用的类型化地址选项进行编译,则编译器会拒绝LPNotify := @LNotify作为类型不匹配。我找不到Embarcadero继续输入默认值为默认禁用的合理解释。

你的函数的最后一行应该是

Caption := Format(
  'Pointer: %d | Value: %d', 
  [Int64(@LNotify), Int64(TMethod(LPNotify^))]
);

我假设您使用32位编译器进行Int64演员表。