TInterfacedObject 自动内存管理是否也适用于 C++Builder?
Does TInterfacedObject automatic memory management also work with C++Builder?
博客文章“Application Development with C++Builder and Delphi”说
Almost anything you write in Delphi can easily be used in C++Builder
(...) You can write an object once for a Delphi project, and then
reuse it, unchanged, in a C++ project.
关于 TInterfacedObject 及其基于引用计数的自动内存管理,这是否也适用于 C++Builder 而不会造成内存泄漏?还是基于 C++ 的内存管理与这种基于引用计数接口的技术不兼容?
Delphi / C++ documentation for TInterfacedObject 说(由我突出显示):
TInterfacedObject provides basic reference-counting functionality that
makes its descendent classes useful in both Delphi and C++ code.
请注意:这个问题是关于在 C++Builder 项目中直接编译 Delphi / Object Pascal 源代码(afaik 在完成 C++Builder 预编译器 运行 之后),而不是通过动态链接 (DLL)
C++ 编译器不会发出代码来调用 AddRef
和 Release
。 C++ 中没有特殊的 interface
类型。相反,您需要确保对 AddRef
和 Release
进行了必要的调用。这通常是通过将原始接口包装在智能指针中来实现的。在 C++-Builder 中,您可以选择使用 DelphiInterface<T>
或 TComInterface<T>
.
Serg 在这篇文章中谈到了这个话题:Consuming Delphi interfaces in Dephi and C++。那篇文章的总结值得重复:
Some details worth being mentioned:
- Delphi interfaces are always derived from IUnknown; a corresponding pure abstract C++ class should also define IUnknown methods;
- Delphi interface type is kind of a pointer to the corresponding C++ abstract class, so sometimes we need one more level of indirection in
C++ code;
- Delphi interface variables are always initialized to nil by the compiler; in C++ we need default constructor to implement the
nil-initialization;
- Delphi interfaces are automatically released (i.e. call IUnknown._Release method) when an interface variable goes out of
scope; In C++ we implement the same functionality in destructor;
- Interface assignment in Delphi implicitly calls _Addref and _Release methods of IUnknown; in C++ we overload the assignment operator to implement the interface assignment correctly;
C++ 编译器不会像 Delphi 那样直接在 __interface
上实现引用计数。但是,System
中有一个方便的模板,用于包装接口和提供引用计数,System::DelphiInterface
, and this is the standard C++ Builder way 编写行为类似于 Delphi 的代码。
在使用接口编译 .pas 文件时,使用它的类型会在 .hpp 文件中自动生成,也可以在您的 C++ 代码中轻松创建。事实上你可能以前见过它们——使用这个模板自动生成的类型名称都以 _di_
开头,例如 Delphi 接口 IMyInterface
的转换是 _di_IMyInterface
.
直接从帮助文件中复制link就是这个例子:
// Interface that exposes an Add(..) method
__interface INTERFACE_UUID("{D0C74612-9E4D-459A-9304-FACE27E3577D}") IAdder : public System::IInterface
{
virtual int __fastcall Add(int I, int J) = 0 ;
};
typedef System::DelphiInterface<IAdder> _di_IAdder;
在你的 C++ 代码中到处使用 _di_Adder
而不是 IAdder
,你会发现你的引用被计算在内。
有用的读物是 entire section on DAX,C++ Builder 中新的(从 XE 开始)标准 COM 系统,它取代了 ATL。可以在早期版本的 CB 中使用它(例如,我在 2010 年使用过),但不受支持。我喜欢认为我通过当时与一些内部 Embarcadero 员工的一些对话鼓励它获得官方支持。 (我不知道我是否真的有任何影响 - 我只是喜欢这样想:)
博客文章“Application Development with C++Builder and Delphi”说
Almost anything you write in Delphi can easily be used in C++Builder (...) You can write an object once for a Delphi project, and then reuse it, unchanged, in a C++ project.
关于 TInterfacedObject 及其基于引用计数的自动内存管理,这是否也适用于 C++Builder 而不会造成内存泄漏?还是基于 C++ 的内存管理与这种基于引用计数接口的技术不兼容?
Delphi / C++ documentation for TInterfacedObject 说(由我突出显示):
TInterfacedObject provides basic reference-counting functionality that makes its descendent classes useful in both Delphi and C++ code.
请注意:这个问题是关于在 C++Builder 项目中直接编译 Delphi / Object Pascal 源代码(afaik 在完成 C++Builder 预编译器 运行 之后),而不是通过动态链接 (DLL)
C++ 编译器不会发出代码来调用 AddRef
和 Release
。 C++ 中没有特殊的 interface
类型。相反,您需要确保对 AddRef
和 Release
进行了必要的调用。这通常是通过将原始接口包装在智能指针中来实现的。在 C++-Builder 中,您可以选择使用 DelphiInterface<T>
或 TComInterface<T>
.
Serg 在这篇文章中谈到了这个话题:Consuming Delphi interfaces in Dephi and C++。那篇文章的总结值得重复:
Some details worth being mentioned:
- Delphi interfaces are always derived from IUnknown; a corresponding pure abstract C++ class should also define IUnknown methods;
- Delphi interface type is kind of a pointer to the corresponding C++ abstract class, so sometimes we need one more level of indirection in C++ code;
- Delphi interface variables are always initialized to nil by the compiler; in C++ we need default constructor to implement the nil-initialization;
- Delphi interfaces are automatically released (i.e. call IUnknown._Release method) when an interface variable goes out of scope; In C++ we implement the same functionality in destructor;
- Interface assignment in Delphi implicitly calls _Addref and _Release methods of IUnknown; in C++ we overload the assignment operator to implement the interface assignment correctly;
C++ 编译器不会像 Delphi 那样直接在 __interface
上实现引用计数。但是,System
中有一个方便的模板,用于包装接口和提供引用计数,System::DelphiInterface
, and this is the standard C++ Builder way 编写行为类似于 Delphi 的代码。
在使用接口编译 .pas 文件时,使用它的类型会在 .hpp 文件中自动生成,也可以在您的 C++ 代码中轻松创建。事实上你可能以前见过它们——使用这个模板自动生成的类型名称都以 _di_
开头,例如 Delphi 接口 IMyInterface
的转换是 _di_IMyInterface
.
直接从帮助文件中复制link就是这个例子:
// Interface that exposes an Add(..) method
__interface INTERFACE_UUID("{D0C74612-9E4D-459A-9304-FACE27E3577D}") IAdder : public System::IInterface
{
virtual int __fastcall Add(int I, int J) = 0 ;
};
typedef System::DelphiInterface<IAdder> _di_IAdder;
在你的 C++ 代码中到处使用 _di_Adder
而不是 IAdder
,你会发现你的引用被计算在内。
有用的读物是 entire section on DAX,C++ Builder 中新的(从 XE 开始)标准 COM 系统,它取代了 ATL。可以在早期版本的 CB 中使用它(例如,我在 2010 年使用过),但不受支持。我喜欢认为我通过当时与一些内部 Embarcadero 员工的一些对话鼓励它获得官方支持。 (我不知道我是否真的有任何影响 - 我只是喜欢这样想:)