Nel seguente codice di esempio la chiamata a AssertTestObj()
causa una violazione di accesso.Come verificare se un riferimento alla procedura è nulla?
Progetto InvokeTest2.exe sollevato classe di eccezione C0000005 $ con il messaggio 'violazione di accesso a 0x00000000: lettura di indirizzo 0x00000000'.
durante il debug posso vedere che il test Assigned(NotifyProc)
in TSafeCall<T>.Invoke()
non funziona come previsto - in modo che Invoke()
cerca di eseguire NotifyProc
che è nil
e provoca la violazione di accesso in tal modo.
Tutte le idee perché questo non riesce e come risolverlo?
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.
segnalato come [RSP-10204] (https://quality.embarcadero.com/browse/RSP-10204) –
@Martin È possibile modificare utilmente la versione per l'aggiornamento 1 XE7, con numero di versione 21.0.17707.5020. Questa è l'ultima, e dove ho fatto i miei test. –