Delphi 如何将未知接口保存到指针?
我可以将未知接口保存到指针吗 例如,我有一个未知的接口,想将其保存到TreeNode数据中Delphi 如何将未知接口保存到指针?,delphi,pointers,interface,Delphi,Pointers,Interface,我可以将未知接口保存到指针吗 例如,我有一个未知的接口,想将其保存到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 Pointe
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
...
您需要捕获接口引用的值,而不是保存引用的变量的地址 那么,这样做:
Node.Data := Pointer(X);
....
X := IInterface(Node.Data);
// use IInterface in preference to IUnknown
但您必须确保正确处理引用计数,因为此强制转换会破坏自动引用计数
因此,在将接口放入节点时,请参考:
Node.Data := Pointer(X);
X._AddRef;
并在修改节点数据或销毁节点时调用\u Release
正如您所发现的,这相当混乱,而且很容易出错。解决这个问题的更好方法是让编译器来完成这项工作。定义一个子类
TTreeNode
,并使树视图使用该子类。忽略节点的数据属性,并使用子类中引入的自己的IInterface
类型的属性
实现这一点的方法是提供一个事件处理程序,它告诉树视图控件创建子类的节点,而不是简单的老式
TTreeNode
。这种技术的例子可以在这里找到:接口是指针,所以可以按原样存储它(不要使用@
操作符)。但是,为了确保接口的生存期,只要节点引用它,就必须手动增加/减少其引用计数,例如:
Node := TreeView1.Items.Add;
Node.Data := Pointer(x);
x._AddRef;
如果数据被修改,还需要调用“发布”。@Remy Lebeau:非常感谢。虽然我看得太高了,但很简单。谢谢大卫。在UI上使用Treeview进行显示时,您的建议会更好。在我的例子中,实际上我正在使用一种虚拟树视图在后台工作,只用于初始化节点(所有工作都在一个过程中)。
x := IUnknown(Node.Data);
procedure TMyForm.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
IUnknown(Node.Data)._Release;
end;