Tuesday, 25 April 2023
  6 Replies
  1.1K Visits
  Subscribe
Hello,

we identified that the generated code of your OpenAPI generator has no handling for freeing sub objects.

Example:

TsgcOpenAPI_ListOrganizationsResponse_Class = class(TsgcOpenAPIClass)
private
Fdata: TArray<TsgcOpenAPI_OrganizationResponse_Class>; // <-- No release of this objects!
Fcount: integer;
F_type: String;
public
class function Read(const aValue: string): TsgcOpenAPI_ListOrganizationsResponse_Class;
public
property Data: TArray<TsgcOpenAPI_OrganizationResponse_Class> read Fdata write Fdata;
property Count: integer read Fcount write Fcount;
property _type: String read F_type write F_type;
end;


In this example the items of the array Data was not released, when the TsgcOpenAPI_ListOrganizationsResponse_Class instance get freed.

The generator should dynamically generate a destructor with special handling for such cases.

Best regards,
Waldemar Derr
1 year ago
·
#1565
Hello,

Yes, it's a known bug, it will be fixed on the next release. Thanks for the feedback.

Kind Regards,
Sergio
1 year ago
·
#1566
Hi Sergio,

until you are ready we use this workaround:


uses

System.Rtti,
System.SysUtils,
System.TypInfo,

sgcHTTP_OpenAPI_Client;

procedure sgcReleaseMembers(const AObject: TsgcOpenAPIClass);

implementation

var
Ctx: TRttiContext;

procedure sgcReleaseMembers(const AObject: TsgcOpenAPIClass);
type
TObjectArray = TArray<TObject>;
PObjectArray = ^TObjectArray;
var
LType: TRttiType;
LProp: TRttiProperty;
begin
LType:=Ctx.GetType(AObject.ClassType);
for LProp in LType.GetProperties do
begin
case LProp.PropertyType.TypeKind of
tkClass:
begin
if not LProp.IsWritable then Continue;

var PropValue:=LProp.GetValue(AObject);
var PropObj:=PropValue.AsObject;

if Assigned(PropObj) then
begin
if PropObj is TsgcOpenAPIClass
then sgcReleaseMembers(TsgcOpenAPIClass(PropObj));
PropObj.Free;
LProp.SetValue(AObject,nil);
end;
end;
tkDynArray:
begin
var CheckType:=Ctx.GetType(LProp.PropertyType.Handle);
if CheckType is TRttiDynamicArrayType then
begin
var ArrType:=TRttiDynamicArrayType(CheckType);
if ArrType.ElementType.TypeKind = tkClass then
begin
var ArrProperty:=LProp.GetValue(AObject);
var ObjArray:=PObjectArray(ArrProperty.GetReferenceToRawData);
if not Assigned(ObjArray) then Continue;

for var cc := 0 to Length(ObjArray^) - 1 do
begin
if Assigned(ObjArray^[cc]) and (ObjArray^[cc] is TsgcOpenAPIClass)
then sgcReleaseMembers(TsgcOpenAPIClass(ObjArray^[cc]));
ObjArray^[cc].Free;
ObjArray^[cc]:=nil;
end;
end;
end;
end;
end;
end;
end;

initialization
Ctx := TRttiContext.Create;

end.


Before a Instance.Free, we call sgcReleaseMembers(Instance).
You can use it for your solution, completely or partially.
1 year ago
·
#1567
Hi,

Thanks for the code!! I really appreciate it.

Kind Regards,
Sergio
1 year ago
·
#1570
Hello,

I've released a new version which includes your fix, thanks for the feedback.

Kind Regards,
Sergio
1 year ago
·
#1583
Hi Sergio,

I can confirm, that the memory leaks are gone in the 2023.4.0 release.

Best regards,
Waldemar
1 year ago
·
#1585
Hi,

Thanks for letting me know.

Kind Regards,
Sergio
  • Page :
  • 1
There are no replies made for this post yet.
Submit Your Response
Upload files or images for this discussion by clicking on the upload button below.
Supported: gif,jpg,png,jpeg,zip,rar,pdf
· Insert · Remove
  Upload Files (Maximum 10MB)