Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Python4Delphi -用TPyDelphiWrapper.WrapInterface包装delphi接口中的错误

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

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

我使用Python3.8和Delphi 10.4.2。

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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
代码运行次数:0
运行
AI代码解释
复制
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
代码运行次数:0
运行
AI代码解释
复制
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
代码运行次数:0
运行
AI代码解释
复制
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-13 22:33:49

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

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

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

https://stackoverflow.com/questions/69556400

复制
相关文章
ruby学习笔记(11)--symbol与hash参数
symbol是啥就不深入的讨论了,只简单说说symbol的好处 ruby内部对于每个对象,都会有一个数字id用来标识并区分,可以用xxx.object_id来查看 puts "0001".object_id puts "0001".object_id puts "0001".object_id puts "0001".object_id 输出结果类似如下: 32088750 32088730 32088710 32088690 可以发现即使是同样内容的字符串"0001",在ruby解释器内部每次也
菩提树下的杨过
2018/01/22
1K0
hash冲突以及hash冲突的解决方法
首先说一下hash冲突吧,hash冲突在hash表中一般情况下是会遇到的; hash冲突指的是你在向hash表中存数据时,首先要通过key值进行指定的hash算法进行计算,然后得到一个值,这个值就是你要将这个key对应的value存入的地址。但是在这个地址中已经有值存在,所以这个时候就发生了hash冲突,不同的key通过hash算法得到了对应的同一个值。
全栈程序员站长
2022/11/07
1.2K0
解决hash冲突的几种方法_hashmap hash冲突
hash函数 首先来说hash函数,java中对象都已一个hashCode() 方法,那为什么还需要hash函数呢?hashCode是在jdk中是有符号int类型,这个一个很大的范围,如果散列表的数组能覆盖所有int值的话,就不需要hash函数了,当然内存不允许我们维护这么大的散列表。这时我们需要hash函数将原始hashCode映射到一个很小的数组上去。 常见的做法是取模法,也是jdk中的实现方式。
全栈程序员站长
2022/09/28
8280
解决hash冲突的几种方法_hashmap hash冲突
递归方法
  递归是指函数直接或间接调用自身的一种编程方法。调用的过程就是“递”,返回的过程就是归。基本上, 所有的递归问题都可以用递推公式来表示。
全栈程序员站长
2022/09/06
3380
递归方法的理解
递归思想算是编程中比较常见但对初学者而言又有些难以理解的方法了。在leetcode上刷了几道题都用递归思想成功解决后觉得应该贯彻互联网的开源共享精神,总结一下自己的爬坑经历了
我爱自然语言处理
2018/05/26
1.1K0
递归方法的理解
hash冲突解决方法
(2)拉链法中的链表上的节点空间是动态申请的,更适合于创造表之前无法确定表长的情况
2019/05/07
1.4K0
ddEntry(hash, key, value, i)方法根据计算出的hash值
ddEntry(hash, key, value, i)方法根据计算出的hash值,将key-value对放在数组table的i索引处。addEntry 是 HashMap 提供的一个包访问权限的方法(就是没有public,protected,private这三个访问权限修饰词修饰,为默认的访问权限,用default表示,但在代码中没有这个default),代码如下:
用户7365393
2021/10/07
7190
Ruby学习笔记之升级ruby的版本
升级ruby版本,有时候安装ruby的版本过低,需要进行升级,例如安装在centos6.7安装fpm需要ruby版本在1.9以上。
Jetpropelledsnake21
2019/04/25
3.2K0
vue的hash路由微信授权方法
示例代码: klren0312/wechatVueHash (github.com)
治电小白菜
2021/12/14
2.6K1
vue的hash路由微信授权方法
当使用vue的hash路由时, 微信授权重定向到前端时, 会把路由放到url最后, 例如
治电小白菜
2021/12/17
2.8K2
vue的hash路由微信授权方法
java 递归方法卡住_递归算法怎么理解
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/04
9320
Ruby执行shell命令的六种方法
在Ruby中,执行shell命令是一件不奇怪的事情,Ruby提供了大概6种方法供开发者进行实现。这些方法都很简单,本文将具体介绍一下如何在Ruby脚本中进行调用终端命令。
技术小黑屋
2018/09/04
3.3K0
Java递归方法求100的阶乘
//求100! import java.math.BigInteger; public class GetFactorial { public static void main(String[] args) { System.out.println(mul(new BigInteger("100")).toString()); } public static BigInteger mul(BigInteger i) { if (i.intValue() > 1) { Integer
yangjiao
2021/03/04
1.8K0
Java方法的嵌套与递归调用
方法嵌套的概念其实比较好理解,就是在调用方法的过程中又遇到了方法的调用,在刚开始接触的时候虽然在逻辑上能够理解为什么运行结果是这样的,但是对于代码执行的过程还是感觉有些绕。
一头小山猪
2020/04/08
2.5K0
Java方法的嵌套与递归调用
导出域内用户hash的几种方法
在渗透测试期间,可以利用域管权限对域内用户hash进行导出和破解。这些域内用户hash存储在域控制器(NTDS.DIT)中的数据库文件中,并带有一些其他信息,如组成员身份和用户。
Jumbo
2018/07/26
5K0
导出域内用户hash的几种方法
Ruby设计模式透析之 —— 模板方法(Template Method)
Java设计模式透析之 —— 模版方法(Template Method) 今天你还是像往常一样来上班,一如既往地开始了你的编程工作。 项目经理告诉你,今天想在服务器端增加一个新功能,希望写一个方法,
用户1158055
2018/01/05
8730
Ruby设计模式透析之 —— 模板方法(Template Method)
Ruby Programming | 连载 03 - Ruby 对象基础
Ruby 中所有的数据结构和值都是对象,包括基本的数字和字符串以及数组 Array、散列表 Hash 这样的复杂数据结构。
RiemannHypothesis
2022/10/05
2K0
Ruby Programming | 连载 03 - Ruby 对象基础
为什么说二叉树遍历用递归的方法不如非递归方法?
作者:find goo 链接:https://www.zhihu.com/question/24976589/answer/128338947 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
九州暮云
2019/08/21
1K0
Windows - Hash散列值抓取方法
LM Hash(LAN Manager Hash)其本质是 DES 加密。在 Windows 2008 及开始之后默认禁用的是 LM Hash。
渗透攻击红队
2020/11/25
1.9K0
Windows - Hash散列值抓取方法
点击加载更多

相似问题

Ruby中的嵌套Hash遍历递归

21

ruby中的递归Hash变换函数

38

Hash方法get on ruby

234

Ruby LDAP to_hash方法

10

Ruby方法双Splat与Hash

25
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文