【发布时间】:2018-02-08 13:15:46
【问题描述】:
此问题中接受的答案显示了如何在 Delphi 中检查和使用 VCL 派生对象上的接口。
How to use Interface with VCL Classes - Part 2
procedure Test;
var
O1: TSomeThing;
Intf: ISomething;
begin
O1 := TSomeThing.Create(nil);
if Supports(O1, ISomething, Intf) then
begin
Intf.DoSomething;
end;
基本上,我想在 C++Builder 中做同样的事情,但还没有弄清楚如何使用 C++ 中的“支持”。
在使用 VCL 派生类时尝试使用 <dynamic_cast> 在编译时失败...
TSomeThing * O1;
ISomething *i = dynamic_cast<ISomething*>(O1); // Error: Can't cast
建议的Inheritance and Interfaces 文章提到了TObject::GetInterface(),但是当我尝试时收到错误“已调用纯虚函数”。
_di_IFoo mc;
if (this->GetInterface(mc)) ...
更新:首先,我添加接口的对象是现有的 VCL 控件,因此不是从 TInterfacedObject 派生的。
第二个 - 不涉及 COM - 我希望! Interfaces 的使用纯粹是为了让我可以使用接口的概念与 C++Builder(至少在 2010 年)不支持的 VCL 组件进行多重继承。
所以我的界面看起来像这样(注意没有__addref/__release 等...):
__interface INTERFACE_UUID("{C527B88F-3F8E-1134-80e0-01A04F57B270}") IMyInterface : public IInterface
{
public:
virtual UTF8String getHello() = 0;
};
我的对象看起来像这样
class TMyPanel: public TPanel, IMyInterface
{
...
public:
UTF8String getHello() { return "Hello from a TMyPanel";}
...
};
class TMyLabel: public TLabel, IMyInterface
{
...
public:
UTF8String getHello() { return "Hello from a TMyLabel";}
...
};
这很简单,正如 Embarcadero 接口文档中所述。
但是,如何判断一个特定的TObject 是否支持IMyInterface???
以下模板函数为我执行此操作,基于来自system.pas 的TObject.GetInterfaceEntry():
template<typename T>
T* getInterface(TObject *obj)
{
T *intf = NULL;
PInterfaceEntry interfaceEntry = obj->GetInterfaceEntry(__uuidof(T) );
if (interfaceEntry && interfaceEntry->IOffset != 0)
{
intf = (T*)(((char *)obj) + interfaceEntry->IOffset);
}
return intf;
}
我们这样使用它:
IMyInterface *myIf = getInterface<IMyInterface>(aRandomTObject);
if (myIf)
{
UTF8String s = myIf->getHello();
}
如果有比这更好的方法,请告诉我,因为 VTable/Pointer spelunking 让我的牙齿发痒......
【问题讨论】:
-
@J... 也许我很笨,需要用勺子喂食,但我之前读过那个页面,找不到一个例子来说明如何确定一个对象是否支持特定的界面。
-
@J... 不,对象类型在编译时是未知的,并且 - 因为我正在向 VCL 控件添加接口,所以它们不是从 TInterfacedObject 派生的,所以没有
Supports().我有一个对我有用的“答案”——但感觉很可怕。我会把它贴出来看看谁喝醉了。 -
您不需要
TInterfacedObject来使用Supports()。它可以查询TObject的接口表,然后枚举它以查找请求的接口。 -
@RemyLebeau - 我明白了 - 我可以使用
::Supports()但不能使用this->Supports()??
标签: delphi interface c++builder