I am using python4delphi. How can I return an object from a wrapped Delphi class function?
Code Snippet:
I have a simple Delphi Class that I wrapped to Python Script, right?
TSimple = Class
Private
function getvar1:string;
Public
Published
property var1:string read getVar1;
function getObj:TSimple;
end;
...
function TSimple.getVar1:string;
begin
result:='hello';
end;
function TSimple.getObj:TSimple;
begin
result:=self;
end;
I made the TPySimple like the demo32 to give class access to the Python code. My Python module name is test.
TPySimple = class(TPyDelphiPersistent)
// Constructors & Destructors
constructor Create( APythonType : TPythonType ); override;
constructor CreateWith( PythonType : TPythonType; args : PPyObject ); override;
// Basic services
function Repr : PPyObject; override;
class function DelphiObjectClass : TClass; override;
end;
...
{ TPySimple }
constructor TPySimple.Create(APythonType: TPythonType);
begin
inherited;
// we need to set DelphiObject property
DelphiObject := TSimple.Create;
with TSimple(DelphiObject) do begin
end;
Owned := True; // We own the objects we create
end;
constructor TPySimple.CreateWith(PythonType: TPythonType; args: PPyObject);
begin
inherited;
with GetPythonEngine, DelphiObject as TSimple do
begin
if PyArg_ParseTuple( args, ':CreateSimple' ) = 0 then
Exit;
end;
end;
class function TPySimple.DelphiObjectClass: TClass;
begin
Result := TSimple;
end;
function TPySimple.Repr: PPyObject;
begin
with GetPythonEngine, DelphiObject as TSimple do
Result := VariantAsPyObject(Format('',[]));
// or Result := PyString_FromString( PAnsiChar(Format('()',[])) );
end;
And now the python code:
import test
a = test.Simple()
# try access the property var1 and everything is right
print a.var1
# work's, but..
b = a.getObj();
# raise a exception that not find any attributes named getObj.
# if the function returns a string for example, it's work.
I have run into the same problem while using DelphiWrapper.
First, enable RTTI using {$METHODINFO ON} will prevent exception:
raise a exception that not find any attributes named getObj.
Write TSimple class like this:
{$METHODINFO ON}
TSimple = Class
Private
function getvar1:string;
Public
Published
property var1:string read getVar1;
function getObj:TSimple;
end;
{$METHODINFO OFF}
Now getObj function returns a value -- an Integer!!
I'll show you guys what I did. I modified Demo32:
Unit1.pas:
TPoint = class(TPersistent)
private
fx, fy : Integer;
fName : String;
public
constructor Create();
procedure OffsetBy( dx, dy : integer );
function MySelf: TPoint; //**access self using function**
published
property x : integer read fx write fx;
property y : integer read fy write fy;
property Name : string read fName write fName;
property MySelf2: TPoint read MySelf; //**access self using property**
end;
Python code in Memo1.Lines:
import spam
p = spam.Point(2, 5)
b = p.MySelf() //**using function**
print 'Using MySelf: ', type(b), b
c = p.MySelf2 //**using property**
print 'Using MySelf2: ', type(c), c
Then it gives a result like this:
Using MySelf: <type 'int'> 31957664
Using MySelf2: <type 'Point'> (2, 5)
The function returns an int, that's wired. Maybe it's a pointer to a TPoint object incorrectly wrapped by DelphiWrapper.
Finally I found a compromise way in Demo8 using "AddMethod". Not beautiful at all!! But it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With