首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
 您现在的位置: 中国IT实验室 >> 游戏开发 >> 游戏开发文档 >> 正文
详细介绍组件对象模型的规则
来源:ChinaItLab 作者: 时间:2004-12-21


  规则1:必须实现Iunknown
  如果一个对象没有至少实现一个最小程度为IUnknown的接口,那它就不是Microsoft的组件对象模型(COM)。
  
  接口设计规则
  接口必须直接或间接地从IUnknown继承。
  
  接口必须有唯一的识别(IID)。
  
  接口是不变的。一旦分配和公布了IID,接口定义的任何因素都不能被改变。
  
  接口的成员函数应该有HRESULT类型的返回值,使远端结构可报告远程过程调用(RPC)错误的情况。
  
  接口成员函数的字符串参数应该是Unicode。
  
  实现 IUnknown
  对象的同一性。这要求对任何特定IUnknown接口的给定对象实例的QueryInterface调用返回相同的物理指针变量。这导致了所谓的两个接口的QueryInterface(IID_IUnknown, ...)和结果的比较,以确定它们是否为同一对象(COM对象同一性)。
  
  静态接口的设置。任何经由QueryInterface来访问对象的接口的设置,必须是静态而不是动态的。也就是说,假如一旦QueryInterface获得了一个给定的IID,那么它总是对相同的对象(除非有意想不到情况)调用,假如QueryInterface不能获得一个给定的IID,那么随后对相同IID的对象调用必定会失败。
  
  对象完整性。对于可处理的接口设置,必须有反身性,对称性和过渡性。即给定代码如下:
  
  IA * pA = (some function returning an IA*);
  IB * pB = NULL;
  HRESULT hr;
  hr = pA->QueryInterface(IID_IB,&pB); // line 4
  Symmetric: pA->QueryInterface(IID_IA, ...) must succeed (a>>a)
  Reflexive: If, in line 4, pB was successfully obtained, then
  pB->QueryInterface(IID_IA, ...)
  must succeed (a>>b, then b>>a).
  Transitive: If, in line 4, pB was successfully obtained, and we do
  IC * pC = NULL;
  hr = pB->QueryInterface(IID_IC, &pC); //Line 7
  and pC is successfully obtained in line 7,then
  pA->QueryInterface(IID_IC, ...)
  must succeed (a>>b, and b>>c,then a>>c).
  
  最小参考服务大小。我们需要实现AddRef来维护一个服务台,它足够大以便支持给定对象的所有接口的2 31 –1有出色的整体指示服务。一个32-位的无符号整型数满足要求。
  
  Release并不意味着失败。假如客户想知道关于资源已被释放等情况,就必须在调用Release之前使用一些对象接口中的较高的语义。
  
  内存管理规则
  接口指针的生命期管理总是通过建立在每个COM接口上的AddRef和Release方法来实现。(参见下面的“引用计数规则”)
  
  下面的规则适用于接口成员函数的参数,包括不是“按值”传递的返回值。
  
  对于参数来说,调用程序应分配和释放内存。
  
  出口参数必须由被调用程序分配,由调用程序用标准的COM内存分配程序来释放。
  
  出入参数首先由调用程序分配,必要时由被调用程序释放及重分配。至于出口参数,调用程序有责任释放最终返回变量。此时必须使用标准的COM内存分配程序。
  
  假如函数返回调用失败的代码,则通常调用者没办法清除出口和入出口参数。这导致了一些附加规则:
  
  错误返回时,出口参数必须可靠地被设置成可清除变量,它不能对调用程序有影响。
  
  此外,所有的出口指针参数(包括调用分配,被调用委任结构)必须被明显地设为NULL。最直接的方法是在函数说明项中设成NULL。
  
  返回错误时,所有的入出口参数必须为被调用者所搁置(这样保持为调用程序初始化的值;若调用程序没有对它初始化,则它是个出口参数,不是入出口参数),或者被明显地设为出口错误返回情况。
  
  参考计数规则:
  规则1:对于接口指针的每一个新的副本,AddRef必须被调用;Release在接口指针的每一个破坏时调用,除了子规则明显允许了其他情况。
  
  以下规则对应于规则1的非例外情况。
  
  规则1a:函数的入口出口参数。调用程序必须AddRef实际参数,因为当出口变量存放在它之上时,将由被调程序释放。
  
  规则1b:获取全局变量。从全局变量的已存在的指针副本得到的接口指针的局部副本,必须被独立地引用计数。因为存在局部副本时,被调函数会破坏全局副本。
  
  规则1c:新指针合成所需资源不多。函数使用内在知识合成接口指针,而不是从其他资源所得,此时必须对新指针做初始AddRef。这样的重要例子有事例生成法则,Iunknown::QueryInterface的实现,等等。
  
  规则1d:内部存储指针副本的返回。指针返回之后,被调程序不知道它的生命期和指针的内部存储副本如何联系。所以,被调程序必须在返回前对指针副本调用AddRef。
  
  规则2:对于接口指针的两个或更多的副本,它们的生命期的起始和终了的关系代码的特定知识,使AddRef/Release可以被省略。
  
  从COM客户的角度,引用计数是和接口对应的概念。客户不应认为对象的所有接口有同一引用计数。
  
  不应依赖于Addref & Release的返回值,而应用于调试目的。
  
  指针稳定性;参见在"Reference-Counting Rules"下的OLE帮助文件中的子部分:"Stabilizing the this Pointer and Keeping it Valid"。
  
  参见Douglas Hodges写的优秀的技术文章"Managing Object Lifetimes in OLE",及Kraig Brockschmidt (MSDN Library, Books)写的Inside OLE的第三章来获取更多信息。
  
  COM申请责任:
  以客户,服务器,对象执行者之一身份使用COM的每一进程,要对三件事负责:
  
  确定COM库是同COM函数CoBuildVersion一致的版本。
  
  在使用其他函数之前通过调用CoInitialize初始化COM库。
  
  在不用CoUninitialize时取消COM库的初始化。
  
  进程内服务器能假定载入的进程已执行了这些步骤。
  
  服务器规则
  进程内服务器必须输出DllGetClassObject and DllCanUnloadNow。
  
  进程内服务器必须支持COM自注册。
  
  进程内和局部服务器应该在它们的文件版本信息中提供OLESelfReg字符串。
  
  进程内服务器必须输出DllRegisterServer and DllUnRegisterServer。
  
  局部服务器应支持/RegServer and /UnRegServer命令行开关。
  
  生成集合对象
  生成可合计的对象是可选的,且操作简单,有诸多益处。以下规则使用于创建可合计的对象(通常称为内部对象)。
  
  由QueryInterface, AddRef, 和 Release对IUnknown接口的内部对象执行单独控制内部接口的引用计数,且不能授权给外部未知指针。这种IUnknown执行称为隐式IUnknown。
  
  内部对象执行接口的QueryInterface, AddRef, 和 Release成员的实行,除了IUnknown自己,都必须授权给外部未知指针。这些实施不能直接影响内部对象的参考计数。
  
  隐式Iunknown只对内部对象实施QueryInterface操作。
  
  集合对象在占用外部未知指针参考时,不能调用AddRef。
  
  如果当对象创建时,需要除Iunknown外的任一接口,创建失败同E_UBKNOWN一起。
  
  以下的代码段阐明了使用嵌套类来实现集合对象接口的范例:
  
  // CSomeObject is an aggregatable object that implements
  // IUnknown and ISomeInterface
  class CSomeObject : public IUnknown
  {
  private:
  DWORD m_cRef;// Object reference count
  IUnknown* m_pUnkOuter; //Outer unknown, no AddRef
  // Nested class to implement the ISomeInterface interface
  class CImpSomeInterface: public ISomeInterface
  {
  friend class CSomeObject ;
  private:
  private:DWORD m_cRef; //Interface ref-count, for debugging
  private:IUnknown*m_pUnkOuter; // Outerunknown, for delegation
  private:public:
  private:CImpSomeInterface() { m_cRef = 0; };
  private:~ CImpSomeInterface(void) {};
  private:// IUnknown members delegate to the outer unknown
  private:// IUnknown members do not control lifetime of object
  private:STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
  private:{ return m_pUnkOuter->QueryInterface(riid,ppv);};
  private:STDMETHODIMP_(DWORD) AddRef(void)
  private:{ return m_pUnkOuter->AddRef(); };
  private:STDMETHODIMP_(DWORD) Release(void)
  private:{ return m_pUnkOuter->Release();};
  private:// ISomeInterface members
  private:STDMETHODIMP SomeMethod(void)
  private:{ return S_OK; };
  private:} ;
  private:CImpSomeInterface m_ImpSomeInterface ;
  private:public:
  private:CSomeObject(IUnknown * pUnkOuter)
  {
  m_cRef=0;
  // No AddRef necessary if non-NULL as we're aggregated.
  m_pUnkOuter=pUnkOuter;
  m_ImpSomeInterface.m_pUnkOuter=pUnkOuter;
  } ;
  // Static member function for creating new instances (don't use
  // new directly).Protects against outer objects asking for interfaces
  // other than IUnknown
  static HRESULT Create(IUnknown* pUnkOuter, REFIID riid, void **ppv)
【责编:admin】

中国IT教育热线咨询

相关文章
游戏开发新手入门之位图化图形
给希望成为游戏美术设计师的朋友
Ogre游戏引擎鼠标选取物体演示  
所有绘画的核心灵魂——素描知识
DirectDraw与DirectInput游戏编程体验
推荐文章

 精彩友情推荐
·Asp源码 PHP源码
·CGI源码 JSP源码
·建站书籍教程
·服务器软件 .net源码
·建站工具软件
·IDC资讯大全
·机房品质万里行
·IDC托管必备知识
·全国IDC报价
·网站推广优化
 基础入门  开发文档
 最新推荐
  多数的Windows程序都需要Windows.h和Windowsx.h这两个头文件,要确保使用它们。当然,你还需要其它......
游戏引擎演化史
在Windows上安装OGRE的方法
关于滤镜遮罩概念,Sobel 遮罩
游戏开发新手入门之Windows编程
游戏开发新手入门之位图化图形
教你实现卡通渲染的另类勾边方法
游戏设计大师谈如何成为一名游戏设
Visual C#编写 3D游戏框架示例
真正的 Java 学习从入门到精通
游戏开发经验——游戏开发的基本常
  为什么要研究攻击行为在人类有记载的5600年的历史中,共计发生了14,400次战争;今天,平均一天要发生............
游戏开发中显示对话的特殊句法
游戏原型设计的介绍
网络游戏中的攻击行为
谈动作类游戏的必要条件
规则的多元分析模式
载入位图文件到DirectDraw
Archer Game Suite 是什么?
浅谈游戏企划-新手入门篇
暴雪称霸游戏业界的六大秘密绝招
骨骼动画及示例Skinned Mesh的解析
  培训中心