如何将未知接口保存到指针?

 心痛则痛1314 发布于 2023-02-08 00:10

我可以将未知接口保存到指针吗?

例如,我有一个未知的接口,并希望将其保存到TreeNode数据?

var
  X : Inknown;

要保存:

....  
  Node:=TreeView1.Items.Add;
  //Node.data:=x; //compiler won't allow this
  Node.data:=@x;
...  

要得到 :

...  
var
  //X:=Node.data; //compiler won't allow this too
  Pointer(X):=Node.data; //an exception caught
...  

Remy Lebeau.. 12

接口是指针,因此您可以按原样存储它(不要使用@运算符).但是,为了确保接口的生命周期,只要节点引用​​它,就必须手动递增/递减其引用计数,例如:

Node := TreeView1.Items.Add;
Node.Data := Pointer(x);
x._AddRef;

x := IUnknown(Node.Data);

procedure TMyForm.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
   IUnknown(Node.Data)._Release;
end;


David Heffer.. 6

您需要捕获接口引用的值,而不是捕获引用的变量的地址.

所以,这样做:

Node.Data := Pointer(X);
....
X := IInterface(Node.Data); 
// use IInterface in preference to IUnknown

但是你必须确保正确处理引用计数,因为这个转换会颠覆自动引用计数.

因此,在将接口放入节点时请参考:

Node.Data := Pointer(X);
X._AddRef;

_Release在修改Node.Data或销毁节点时调用.


正如你所发现的那样,这是相当混乱的,容易出错.解决问题的更好方法是让编译器完成工作.定义子类TTreeNode,并使树视图使用该子类.忽略节点的Data属性并使用您自己的类型属性IInterface,在子类中引入.

实现这一目标的方法是提供一个OnCreateNodeClass事件处理程序,告诉树视图控件创建子类的节点而不是旧的节点TTreeNode.可以在此处找到该技术的示例:https://stackoverflow.com/a/25611921/

2 个回答
  • 接口是指针,因此您可以按原样存储它(不要使用@运算符).但是,为了确保接口的生命周期,只要节点引用​​它,就必须手动递增/递减其引用计数,例如:

    Node := TreeView1.Items.Add;
    Node.Data := Pointer(x);
    x._AddRef;
    

    x := IUnknown(Node.Data);
    

    procedure TMyForm.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
    begin
       IUnknown(Node.Data)._Release;
    end;
    

    2023-02-08 00:31 回答
  • 您需要捕获接口引用的值,而不是捕获引用的变量的地址.

    所以,这样做:

    Node.Data := Pointer(X);
    ....
    X := IInterface(Node.Data); 
    // use IInterface in preference to IUnknown
    

    但是你必须确保正确处理引用计数,因为这个转换会颠覆自动引用计数.

    因此,在将接口放入节点时请参考:

    Node.Data := Pointer(X);
    X._AddRef;
    

    _Release在修改Node.Data或销毁节点时调用.


    正如你所发现的那样,这是相当混乱的,容易出错.解决问题的更好方法是让编译器完成工作.定义子类TTreeNode,并使树视图使用该子类.忽略节点的Data属性并使用您自己的类型属性IInterface,在子类中引入.

    实现这一目标的方法是提供一个OnCreateNodeClass事件处理程序,告诉树视图控件创建子类的节点而不是旧的节点TTreeNode.可以在此处找到该技术的示例:https://stackoverflow.com/a/25611921/

    2023-02-08 00:31 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有