DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: 19137911446
今日帖子: 17
在线用户: 9
导航: 论坛 -> 文档资料 斑竹:liumazi,ruralboy  
作者:
男 sephil (NAILY Soft) ★☆☆☆☆ -
盒子中级会员
2004/4/22 11:01:52
标题:
[原创]在C++Builder中使用IInterface 浏览:4329
加入我的收藏
楼主: 链接: http://www.efile.com.cn/efile/sephil/BCB_IInterface.htm


在C++Builder中使用IInterface
 
Sephil原创        sephil@163.com
 
用过Delphi的人应该知道,Interface可是个好东西
我也是最近才开始研究这个东东
但是我在C++Builder中使用的时候却遇到了麻烦
 
拿我正在写的这个程序举例吧
Delphi中我们会这样写
 
// IFileCommand 接口声明 ========================================
 
......
type
  IFileCommand = interface(IInterface)
    procedure NewFile;
  end;
......
 
// IFileCommand 接口实现 ========================================
 
......
type
  TFileCommand = class(TInterfacedObject, IFileCommand)
  public
    procedure NewFile;
  end;
 
implementation
 
procedure TFileCommand.NewFile;
begin
  // Do something here
end;
......
 
// 使用 IFileCommand 接口 ========================================
 
......
procedure Form1.FormCreate(Sender: TObject);
var
  FFileCommand: IFileCommand;
begin
  FFileCommand := TFileCommand.Create;
  FFileCommand.NewFile;
  FFileCommand := nil;
end;
......
 
上面的代码在Delphi中可以正常编译运行
不过我的程序是用C++Builder写的,因此我需要在C++Builder中实现
于是我按部就班,将代码翻译成BCB的
 
// IFileCommand 接口声明 ========================================
 
......
__interface IFileCommand : public IInterface
{
public:
    virtual void __fastcall NewFile() = 0;
};
typedef DelphiInterface<IFileCommand> _di_IFileCommand;
......

 
// IFileCommand 接口实现 ========================================
 
......
__interface TFileCommand : public TInterfacedObject, public IFileCommand
{
public:
    virtual void __fastcall NewFile()
    { /* Do something */ };
};
......
 
// 使用 IFileCommand 接口 ========================================
 
......
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
    _di_IFileCommand FFileCommand;
    FFileCommand = new TFileCommand();
    FFileCommand->NewFile();
    FFileCommand = NULL;   
}
......
 
可是编译的时候BCB提示错误,说是Cannot create instance of abstract class 'TFileCommand'
虽然以前也用BCB写过AutomationObject,不过对这种Internal Interface我还真不知道怎么处理
于是上网查资料,花了2个多小时,找到的都是BCB用ATL实现COM Interface之类,没什么用,只好自己回来慢慢试
又花了一个多小时,在编译时无意中发现BCB有这么一句提示: 'TFileCommand' is abstract because of '__stdcall IUnknown::QueryInterface(const _GUID &, void**) = 0'
faint!原来是这么回事
IInterface是继承自IUnknown接口的,而IUnknown有三个虚方法:AddRef Release 和 QueryInterface
Delphi中的IInterface实现了这几个方法,因此继承自IInterface的接口不必程序员自己再实现
而BCB中的IInterface却并没有实现这几个方法,因此需要自己实现
 
代码如下
 
// IFileCommand 接口实现 ========================================
......
class TFileCommand : public TInterfacedObject, public IFileCommand
{
public:
    virtual void __fastcall NewFile()
    { /* Do something */ };

 
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(
            /* [in] */ REFIID riid,
            /* [iid_is][out] */ void **ppvObject)
    { return TInterfacedObject::QueryInterface(riid, ppvObject); };

    virtual ULONG STDMETHODCALLTYPE AddRef( void)
    { return TInterfacedObject::_AddRef(); };

    virtual ULONG STDMETHODCALLTYPE Release( void)
    { return TInterfacedObject::_Release(); };
};
......
 
其实你不需要自己处理,之需要简单的返回 TInterfacedObject 的实现即可
 
很简单吧,555,我可是花了几个小时才搞明白
在这里我也提醒大家一句,编译出错时一定要仔细看看错误信息,一般编译器给出的错误信息都是很有用的
 
好了,就说到这里,希望这点小小的经验能对大家有点帮助
有什么不对的地方,也请大家指正

                                                                                2004.04.21
----------------------------------------------
Copyright 2008 ? NAILY Soft

Click here to redirect to my home
Click here to redirect to my blog
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行171.875毫秒 RSS