Skip to content

Commit 83f6b5e

Browse files
committed
Handle Pointer fields, properties and parameters - stored as python integers.
1 parent e016456 commit 83f6b5e

File tree

3 files changed

+32
-11
lines changed

3 files changed

+32
-11
lines changed

Source/PythonEngine.pas

+1-1
Original file line numberDiff line numberDiff line change
@@ -1649,7 +1649,7 @@ TPythonInterface=class(TDynamicDll)
16491649
PyLong_FromLongLong:function(val:Int64): PPyObject; cdecl;
16501650
PyLong_FromUnsignedLongLong:function(val:UInt64) : PPyObject; cdecl;
16511651
PyLong_AsLongLong:function(ob:PPyObject): Int64; cdecl;
1652-
PyLong_AsVoidPtr:function(ob:PPyObject): Pointer;
1652+
PyLong_AsVoidPtr:function(ob:PPyObject): Pointer; cdecl;
16531653
PyLong_FromVoidPtr:function(p: Pointer): PPyObject; cdecl;
16541654
PyMapping_Check:function (ob:PPyObject):integer; cdecl;
16551655
PyMapping_GetItemString:function (ob:PPyObject;key:PAnsiChar):PPyObject; cdecl;

Source/WrapDelphi.pas

+22-10
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,7 @@ implementation
10421042
rs_ExpectedNil = 'In static methods Self should be nil';
10431043
rs_ExpectedInterface = 'Expected a Pascal interface';
10441044
rs_ExpectedSequence = 'Expected a python sequence';
1045-
rsExpectedPPyObject = 'Expected a PPyObject';
1045+
rsExpectedPointer = 'Expected a Pointer';
10461046
rs_InvalidClass = 'Invalid class';
10471047
rs_ErrEventNotReg = 'No Registered EventHandler for events of type "%s';
10481048
rs_ErrEventNoSuport = 'Class %s does not support events because it must '+
@@ -2188,23 +2188,38 @@ function ValidateDynArray(PyValue: PPyObject; const RttiType: TRttiType;
21882188
end;
21892189
end;
21902190

2191-
function ValidatePPyObject(PyValue: PPyObject; const RttiType: TRttiType;
2191+
function ValidatePointer(PyValue: PPyObject; const RttiType: TRttiType;
21922192
out ParamValue: TValue; out ErrMsg: string): Boolean;
21932193
var
21942194
RefType: TRttiType;
2195+
PyEngine: TPythonEngine;
2196+
P: Pointer;
21952197
begin
21962198
Result := False;
2199+
PyEngine := GetPythonEngine;
2200+
21972201
if (RTTIType is TRttiPointerType) then
21982202
begin
21992203
RefType := TRttiPointerType(RTTIType).ReferredType;
22002204
if Assigned(RefType) and (RefType.Name = 'PyObject') then
22012205
begin
22022206
Result := True;
22032207
ParamValue := TValue.From<PPyObject>(PyValue);
2208+
end
2209+
else if PyEngine.PyLong_Check(PyValue) then
2210+
begin
2211+
P := PyEngine.PyLong_AsVoidPtr(PyValue);
2212+
if PyEngine.PyErr_Occurred = nil then
2213+
begin
2214+
Result := True;
2215+
ParamValue := TValue.From<Pointer>(P);
2216+
end
2217+
else
2218+
PyEngine.PyErr_Clear;
22042219
end;
22052220
end;
22062221
if not Result then
2207-
ErrMsg := rsExpectedPPyObject;
2222+
ErrMsg := rsExpectedPointer;
22082223
end;
22092224

22102225
function PyObjectToTValue(PyArg: PPyObject; ArgType: TRttiType;
@@ -2238,7 +2253,7 @@ function PyObjectToTValue(PyArg: PPyObject; ArgType: TRttiType;
22382253
tkDynArray:
22392254
Result := ValidateDynArray(PyArg, ArgType, Arg, ErrMsg);
22402255
tkPointer:
2241-
Result := ValidatePPyObject(PyArg, ArgType, Arg, ErrMsg);
2256+
Result := ValidatePointer(PyArg, ArgType, Arg, ErrMsg);
22422257
else
22432258
Result := SimplePythonToValue(PyArg, ArgType.Handle, Arg, ErrMsg);
22442259
end;
@@ -2277,7 +2292,7 @@ function TValueToPyObject(const Value: TValue;
22772292
DelphiWrapper: TPyDelphiWrapper; out ErrMsg: string): PPyObject;
22782293
begin
22792294
if Value.IsEmpty then
2280-
Result := GetPythonEngine.ReturnNone
2295+
Result := DelphiWrapper.Engine.ReturnNone
22812296
else
22822297
case Value.Kind of
22832298
tkClass: Result := DelphiWrapper.Wrap(Value.AsObject);
@@ -2288,13 +2303,10 @@ function TValueToPyObject(const Value: TValue;
22882303
tkArray, tkDynArray:
22892304
Result := DynArrayToPython(Value, DelphiWrapper, ErrMsg);
22902305
tkPointer:
2291-
if Value.IsType<PPyObject> then
2306+
if Value.TypeInfo = TypeInfo(PPyObject) then
22922307
Result := Value.AsType<PPyObject>
22932308
else
2294-
begin
2295-
Result := nil;
2296-
ErrMsg := rs_ErrValueToPython;
2297-
end;
2309+
Result := DelphiWrapper.Engine.PyLong_FromVoidPtr(Value.AsType<Pointer>);
22982310
else
22992311
Result := SimpleValueToPython(Value, ErrMsg);
23002312
end;

Tests/WrapDelphiTest.pas

+9
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ TTestRttiAccess = class
5555
ObjectField: TObject;
5656
RecordField: TTestRecord;
5757
InterfaceField: ITestInterface;
58+
PointerField: Pointer;
5859
ClassRef: TClass;
5960
function GetData: TObject;
6061
procedure BuyFruits(AFruits: TFruits);
@@ -160,6 +161,8 @@ TTestWrapDelphi = class(TObject)
160161
procedure TestVarArgs;
161162
[Test]
162163
procedure TestPPyObjects;
164+
[Test]
165+
procedure TestPointers;
163166
end;
164167

165168
implementation
@@ -439,6 +442,12 @@ procedure TTestWrapDelphi.TestPPyObjects;
439442
Assert.AreEqual<string>(List.GetItem(0), 'abc');
440443
end;
441444

445+
procedure TTestWrapDelphi.TestPointers;
446+
begin
447+
rtti_var.PointerField := $FFFF;
448+
Assert.AreEqual<NativeUInt>(rtti_var.PointerField, $FFFF);
449+
end;
450+
442451
procedure TTestWrapDelphi.TestRecord;
443452
begin
444453
Rtti_rec.StringField := 'abcd';

0 commit comments

Comments
 (0)