Paul
Paul

Reputation: 26680

Access violation after going out of a RTTI-related function: Result disappears

Previously I had one function to get object property through RTTI and set it's value. Now I decided to split it up in TRTTI.GetObjProp and TRTTI.SetObjPropValue in order to cache value returned by TRTTI.GetObjProp and speed up data processing.

Strange things happen after that. First of all, I suddenly noticed that ctx.GetType works and has always worked although I never initialized the ctx variable. Ok, if I initialize it with TRttiContext.Create(), nothing changes in the second weirdness:

I call the TRTTI.GetObjProp function and as long as I am in this function, Result is defined, and I can request it's properties with debugger. When I go out of the function, I try to request the same properties of rprop variable and get Access Violation error. According to debugger, rprop is defined.

procedure TConfManager._setValue(indicator: TComponent; name: string; value: OleVariant);
var
  rprop: TRttiProperty;
begin
  rprop := TRTTI.GetObjProp(indicator, name);
  //Access violation here when I try to use rprop
  TRTTI.SetObjPropValue(indicator, rprop, value);
end;

class function TRTTI.GetObjProp(obj: TObject; propName: string): TRttiProperty;
var
  ctx: TRttiContext;
  rtyp: TRttiType;
begin
  if obj = nil then Exit(nil);
  rtyp := ctx.GetType(obj.ClassType);
  Result := rtyp.GetProperty(propName);
end;

Why the function result is properly defined when I am in the function, but isn't properly defined when I go out of it?

Upvotes: 2

Views: 362

Answers (1)

David Heffernan
David Heffernan

Reputation: 613332

The TRttiProperty instance is owned by the TRttiContext object. When your local variable ctx leaves scope, that TRttiContext object is destroyed, taking with it all the objects it owns, including your TRttiProperty instance.

You need to make sure that the TRttiContext object that owns any RTTI objects that you use lives at least as long as any references to those owned objects. The simplest way to achieve that is probably to make the TRttiContext object be a global variable.

Upvotes: 5

Related Questions