首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python4Delphi -用TPyDelphiWrapper.WrapInterface包装delphi接口中的错误

Python4Delphi -用TPyDelphiWrapper.WrapInterface包装delphi接口中的错误
EN

Stack Overflow用户
提问于 2021-10-13 13:24:49
回答 1查看 270关注 0票数 0

我使用Python3.8和Delphi 10.4.2。

我正在尝试使用Python4Delphi的组件通过一个Python访问一些在Delphi中定义的接口。

在设计时,我将TPythonEngine、TPythonModule和TPyDelphiWrapper组件添加到项目的VCL表单中。

因此,我定义了3个接口,分别由3个类实现,如下所示

代码语言:javascript
复制
type
  IPerson = interface (IUnknown)
    ['{1D21B5B6-25DE-4884-8BDB-8E2D9A239D64}']
    function GetName : string;
    procedure SetName ( value : string );
    property Name: string read GetName write SetName;   
    function GetSurname: string;
    procedure SetSurname(value : string);
    property Surname : string read GetSurname write SetSurname;    
    function GetInfo : string;
  end;

  ICustomer = interface (IPerson)
    ['{8742364C-33E8-4FF4-86FB-C19AF67A735B}']
    function GetCustomerNumber : string;
    procedure SetCustomerNumber ( value : string );
    property CustomerNumber : string read GetCustomerNumber write SetCustomerNumber;
  end;

  ISupplier = interface ( IPerson )
    ['{420FFF78-92DE-4D7E-9958-FDA95748EEB7}']
    function GetSupplierNumber : string;
    procedure SetSupplierNumber ( value : string );
    property SupplierNumber : string read GetSupplierNumber write SetSupplierNumber;
  end;

  TPerson = class ( TInterfacedObject , IPerson)
  private
    FName : string;
    FSurname : string;    
    function GetName : string;
    procedure SetName ( value : string );    
    function GetSurname: string;
    procedure SetSurname(value : string);

  public
    property Surname : string read GetSurname write SetSurname;
    property Name: string read GetName write SetName;    
    function GetInfo : string; virtual;
  end;


  TCustomer = class ( TPerson , ICustomer)
  private
    FCustomerNumber : string;
    function GetCustomerNumber : string;
    procedure SetCustomerNumber ( value : string);

  public    
    property CustomerNumber : string read GetCustomerNumber write SetCustomerNumber;
    function GetInfo: string; override;
  end;


  TSupplier = class ( TPerson , ISupplier)
  private
    FSupplierNumber : string;
    function GetSupplierNumber : string;
    procedure SetSupplierNumber ( value : string );

  public
    property SupplierNumber : string read GetSupplierNumber write SetSupplierNumber;
    function GetInfo : string; override;
  end;

在表单的Create方法中,我定义了3个变量,每个变量对应3个接口,通过PyDelphiWrapper,我在3个不同的Python变量中将它们传递给Python模块。

代码语言:javascript
复制
procedure TFrmTestInterface.FormCreate(Sender: TObject);
var
  LPerson : IPerson;
  LCustomer : ICustomer;
  LSupplier : ISupplier;
  Py: PPyObject;
begin

  LPerson := TPerson.Create;
  LCustomer := TCustomer.Create;
  LSupplier := TSupplier.Create;

  LPerson.Name := 'Pippo';
  LPerson.Surname := 'Rossi';

  LCustomer.Name := 'Pluto';
  LCustomer.Surname := 'Verdi';

  LSupplier.Name := 'Paperino';
  LSupplier.Surname := 'Bianchi';


  Py := PyDelphiWrapper1.WrapInterface(TValue.From(LPerson));
  PythonModule1.SetVar('delphi_person', Py);
  GetPythonEngine.Py_DecRef(Py);

  Py := PyDelphiWrapper1.WrapInterface(TValue.From(LCustomer));
  PythonModule1.SetVar('delphi_customer', Py);
  GetPythonEngine.Py_DecRef(Py);

  Py := PyDelphiWrapper1.WrapInterface(TValue.From(LSupplier));
  PythonModule1.SetVar('delphi_supplier', Py);
  GetPythonEngine.Py_DecRef(Py);

end;

在运行时,变量被正确地解释,但是每次我试图访问接口中定义的属性之一时,我总是得到相同的错误。

这是我试图运行的Python脚本:

代码语言:javascript
复制
from delphi_module import delphi_person, delphi_customer, delphi_supplier 

print('type(delphi_person) = ', type(delphi_person)) 
print('type(delphi_customer) = ', type(delphi_customer)) 
print('type(delphi_supplier) = ', type(delphi_supplier)) 

print(delphi_person.Name)

我所犯的错误

回溯(最近一次调用):AttributeError中的文件"",第7行:获取属性"Name“中的错误。错误:未知属性

类型(.)命令对这三个变量正确运行。

如果没有使用接口类型的3个变量,而是将每个变量声明为类类型,使用PyDelphiWrapper.Wrap方法,一切都可以正常工作!

代码语言:javascript
复制
procedure TFrmTestInterface.FormCreate(Sender: TObject);
var
  LPerson : IPerson;
  LCustomer : ICustomer;
  LSupplier : ISupplier;
  Py: PPyObject;
begin

  LPerson := TPerson.Create;
  LCustomer := TCustomer.Create;
  LSupplier := TSupplier.Create;

  LPerson.Name := 'Pippo';
  LPerson.Surname := 'Rossi';

  LCustomer.Name := 'Pluto';
  LCustomer.Surname := 'Verdi';

  LSupplier.Name := 'Paperino';
  LSupplier.Surname := 'Grandi';


  Py := PyDelphiWrapper1.Wrap(LPerson, TObjectOwnership.soReference);
  PythonModule1.SetVar('delphi_person', py);
  GetPythonEngine.Py_DECREF(py);

  Py := PyDelphiWrapper1.Wrap(LCustomer, TObjectOwnership.soReference);
  PythonModule1.SetVar('delphi_customer', py);
  GetPythonEngine.Py_DECREF(py);

  Py := PyDelphiWrapper1.Wrap(LSupplier, TObjectOwnership.soReference);
  PythonModule1.SetVar('delphi_supplier', py);
  GetPythonEngine.Py_DECREF(py);

end;

使用相同的Python脚本,我获得了正确的输出,没有错误。

有人知道我在使用TPyDelphiWrapper包装接口类型变量时做错了什么吗?

EN

回答 1

Stack Overflow用户

发布于 2021-10-14 06:33:49

Delphi没有在接口中定义的属性上添加RTTI。因此,Python引擎找不到属性'Name‘。在接口声明之前添加{$M+}时,RTTI可用于方法。那么,调用delphi_person.GetName()应该可以工作。

使用接口和Python还有另一个问题,当您调用WrapInterface时,接口不会被锁定。因此,当对象超出作用域时,它将被释放。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69556400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档