В следующем примере кода вызов AssertTestObj()
вызывает нарушение прав доступа.
Project InvokeTest2.exe повышает класс исключений $C0000005 с сообщением "Нарушение доступа при 0x00000000: чтение адреса 0x00000000".
При отладке я вижу, что тест Assigned(NotifyProc)
в TSafeCall<T>.Invoke()
работает не так, как ожидалось, так что Invoke()
пытается выполнить NotifyProc
, который является nil
и, следовательно, нарушает прав доступа.
Любые идеи, почему это не удается и как его решить?
program InvokeTest2;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
type
TSafeCall<T> = class
public
type
TNotifyProc = reference to procedure (Item: T);
class procedure Invoke(NotifyProc: TNotifyProc; Item: T); overload;
end;
TOnObj = procedure (Value: String) of object;
{ TSafeCall<T> }
class procedure TSafeCall<T>.Invoke(NotifyProc: TNotifyProc; Item: T);
begin
if Assigned(NotifyProc) then
NotifyProc(Item);
end;
procedure AssertTestObj(OnExceptionObj_: TOnObj; Value_: String);
begin
TSafeCall<String>.Invoke(OnExceptionObj_, Value_);
end;
begin
try
TSafeCall<String>.Invoke(nil, 'works as expected');
AssertTestObj(nil, 'this causes an access violation!');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.