delphi - Why is the captured parameter reset in this anonymous method? -
The following article is based on this article:
When the reward handler code is inside an anonymous process (when a line is changed in the grid) has been removed, the first 'if' report indicates that the DBGR is not zero, but the second report is zero.
Any ideas about what's going on here? You can get the full source code from (You may have to change the filename property of TClientDataSet to point to that document where you unzipped the project.)
Unit Head; Interface access to Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Vcl.DBGrids, Datasnap.DBClient Does, Vcl.Grids; Type AfterScrollEventHandler = Reference Process (Sender: TDataSet); TForm3 = Class (TForm) DBGradrid: TDBGrid; CDDetset: TClientDataSet; DsDataSet: TDataSource; Process formulas (sender: toobject); Private {Private Announcement} public {public declaration} end; Modification process methodofoodetate (constant metathof; var methapet); Process InjectEventHandler (Dataset: TDataSet; dbGrid: TDBGrid); Var form 3: Teform 3; Implementation {$ R *. Dfm} Process InjectEvent Handler (Dataset: TDThat; DBGrid: TDBGrid); Var EventHolder: AfterScrollEventHandler; EventHandlerPtr: TDataSetNotifyEvent; Start eventHandlerRef: = Process (Sender: TDTasset) starts if the DBGrand & lt; & Gt; Neil then MessageDlg ('1: AfterScroll: Grid is not zero!', MTInformation, [MBOK], 0) Other MessageDlg ('1: Scroll after: Grid is Zero! It's crashing ...' MTInformation, [ MBOK], 0); If the DBGrid & lt; & Gt; Neil then MessageDlg ('2: AfterScroll: The grid is not zero!', MtInformation, [mbOK], 0) Other MessageDlg ('2: AfterScroll: The grid is zero! It's crashing ...' MTInformation, [MBOK] , 0); End; Lawrence Robertson (EventHandlerRF, EventHandlerPT); DataSet.AfterScroll: = eventHandlerPtr; End; Modification process methodofoodetate (constant metathof; var methapet); Type TVtable = array [0..3] of pointer; PVBBL = ^ TVTB; PPVBL = ^ PVBubble; Starting 3/3 is the offset of inserts, qi, adrof, after release tmth (methapet) Codes: = PPVable (Mathew) ^^ [3]; TMethod (Methapet). Data: = Pointer (Methaffer); End; Process TForm3.FormCreate (Sender: TObject); Var EventHolderRaPa 1, EventHandlerRep 2: AfterScrollAventHandler; Start InjectEventHandler (cdsDataSet, dbgrdGrid); End. Update:
This code works as expected (anonymous process stores the dbGrid parameter in a local variable):
Process Inject Handler (Dataset: TDThat; DBGrid: TDBGrid); Var EventHolder: AfterScrollEventHandler; EventHandlerPtr: TDataSetNotifyEvent; Starting Hands: Rare: Process (Sender: TDTets) Var Grid: TDBGrid; Start grid: = DBGrid; If the grid & lt; & Gt; Neil then MessageDlg ('1: AfterScroll: Grid is not zero!', MTInformation, [MBOK], 0) Other MessageDlg ('1: Scroll after: Grid is Zero! It's crashing ...' MTInformation, [ MBOK], 0); If the grid & lt; & Gt; Neil then MessageDlg ('2: AfterScroll: The grid is not zero!', MtInformation, [mbOK], 0) Other MessageDlg ('2: AfterScroll: The grid is zero! It's crashing ...' MTInformation, [MBOK] , 0); End; Lawrence Robertson (EventHandlerRF, EventHandlerPT); DataSet.AfterScroll: = eventHandlerPtr; End;
You are looking at undefined behavior refers to the article that you quoted in that reference to the method You need to be alive for the lifetime of the method indicator, but your code breaks that rule. The object associated with the reference method can be destroyed, hence the dbGrid variable, which is the value captured No longer holds it. You are reading the values of the garbage, and it is possible that the space in memory will change the values between the first and the second reading. We do not even know that the value you read is equal to the price you expect, it is not just zero. It seems that when you use local variables, whatever memory is written between the first and the second reading, apparently no longer depends on it where the function is called DbGrid or grid is expected to stay in the variable, although you are still reading garbage. It is just garbage which is not zero twice, instead of once. Make your eventHandlerRef variable an area of an enclosed class instead of a local variable, and all should be okay, assuming the undocumented implementation details for Delphi 2010 still be used by you Are valid in the version.
Comments
Post a Comment