我正在尝试更改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;
韩国社交协会
答案 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
演员表。