0
I’m creating a routine to instantiate a class via RTTI
and validate whether this class implements a interface
.
I have a test class implemented as follows:
unit teste.classeTeste.uclasseTeste;
interface
uses
validador;
type
ClasseTeste = class(TInterfacedObject, IServico)
private
public
function foo: string;
end;
implementation
{ classe }
function ClasseTeste.foo: string;
begin
Result := 'Teste foo';
end;
initialization
ClasseTeste.ClassName;
end.
And I have a Validator class implemented as follows:
unit validador;
interface
uses
Rtti;
type
IServico = interface
['{46C26FED-AEDD-456F-B182-DEECB780D264}']
end;
Svc = class
public
function Validar(pClassName: string): Boolean;
end;
implementation
uses
SysUtils;
{ Svc }
function Svc.Validar(pClassName: string): Boolean;
var
lContext: TRttiContext;
lType: TRttiInstanceType;
lObj: TObject;
begin
Result := False;
lType := lContext.FindType(pClassName) as TRttiInstanceType;
if lType = nil then
raise Exception.Create('Classe solicitada não encontrada no sistema ou ClassNameInválido');
lObj := lType.GetMethod('Create').Invoke(lType.MetaclassType, []).AsObject;
try
if not Supports(lObj, IServico) then
raise Exception.Create('A classe serviço não implementa a interface IServico!');
finally
lObj.Free;
end;
Result := True;
end;
end.
The question is: In the Validate method, in the line
`lObj.Free`;
It bursts
"Invalid Pointer Operation".
Theoretically I have a TObject
instantiated. It needs to be released at some point. How and when I release it?
Note: I am using Delphi 2010.
You passed
'ClasseTeste'
for the execution of your trial?– DH.
Actually, for RTTI to work, I have to pass namespace + class. The call was: if objValidador.Validate('test.classeTeste.uclasseThis.Classeteste') then Showmessage('Validate Class!');
– Nanon
Sorry, but I need to learn how to use this editor yet...
– Nanon
I think it’s because it’s derived from
interface
, and then Delphi itself gets rid of the instance. Test with theReportMemoryLeaksOnShutdown := True
, and do not execute theFree
. If when closing the application does not show a message with "Classeteste X1" then what I said is happening.– DH.
In Delphi 2010, Fastmm does not come embedded. I added and rode. Without giving the Free it does not accuse any "Memoryleak". I created a new variable (lob2), I created the create and did not give the Free, and accused the "Memoryleak". Anyway, I was afraid because lObj := lType.Getmethod('Create'). Invoke(lType.Metaclasstype, []). Asobject; in my view, it would return me a Tobject and not an interface.
– Nanon
I really don’t know how to give you a plausible explanation of why by RTTI it is using management via
interface
since you’re saying you want to create a Classeteste and not an Iservico. Really, if you create a variable that even if you inherit an interface, but you define that the variable is Classeteste, it wasn’t meant to be managed as an interface, and then causes a Memoryleak.– DH.
Still...in Invoke - Invoke(lType.Metaclasstype, []). Asobject - I’m asking him to return me "Asobject" :D
– Nanon