Hello everyone,
I am looking to destroy an object once it is no longer referenced in python.
I am struggeling to correctly do this.
unit Unit1;
interface
uses
SysUtils, Classes,
Windows, Messages, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, ComCtrls,
PythonEngine, Vcl.PythonGUIInputOutput, WrapDelphi;
type
TForm1 = class(TForm)
Splitter1: TSplitter;
Memo1: TMemo;
PythonEngine1: TPythonEngine;
PythonModule1: TPythonModule;
Panel1: TPanel;
Button1: TButton;
PythonGUIInputOutput1: TPythonGUIInputOutput;
Memo2: TMemo;
PyDelphiWrapper1: TPyDelphiWrapper;
procedure Button1Click(Sender: TObject);
private
public
destructor Destroy; override;
function GetDelphiWrapper: TPyDelphiWrapper;
function GetPythonEngine: TPythonEngine;
end;
TEntry = class(TObject)
strict private
FstrName: string;
FclsStringList: TStringList;
public
constructor Create(strName: string);
destructor Destory;
function Name: string;
end;
TManager = class(TObject)
public
function GetNewEntry: PPyObject;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
clsManager: TManager;
pyManager: PPyObject;
begin
clsManager := TManager.Create;
pyManager := PyDelphiWrapper1.Wrap(clsManager, soReference);
PythonModule1.SetVar( 'manager', pyManager );
PythonEngine1.ExecStrings( memo1.Lines );
PythonEngine1.Py_DecRef(pyManager);
end;
{ TManager }
function TManager.GetNewEntry: PPyObject;
begin
// I want TEntry to be destroyed by python once it is no longer used
Result := Form1.GetDelphiWrapper.Wrap(TEntry.Create('Test'), soOwned);
Form1.GetPythonEngine.Py_DECREF(Result);
end;
destructor TForm1.Destroy;
begin
FreeAndNil(PythonModule1);
FreeAndNil(PythonEngine1);
inherited;
end;
function TForm1.GetDelphiWrapper: TPyDelphiWrapper;
begin
Result := PyDelphiWrapper1;
end;
function TForm1.GetPythonEngine: TPythonEngine;
begin
Result := PythonEngine1;
end;
{ TEntry }
constructor TEntry.Create(strName: string);
begin
inherited Create;
FclsStringList := TStringList.Create;
FstrName := strName;
end;
destructor TEntry.Destory;
begin
FreeAndNil(FclsStringList);
inherited;
end;
function TEntry.Name: string;
begin
Result := FstrName;
end;
end.
from spam import *
entry = manager.GetNewEntry()
print(entry.Name())
After clicking the button, I get an exception accessing an invalid pointer.
I also tried returning the object directly instead of wraping it to a PPyObject, but that did not work.
Thank you for your help.
Best regards,
Marcel