没有合适的资源?快使用搜索试试~ 我知道了~
AcDbObjectId、AcDbHandle与AcDbStub之间的关系
需积分: 9 1 下载量 113 浏览量
2012-10-16
14:22:19
上传
评论
收藏 15KB DOCX 举报
温馨提示
试读
2页
AcDbObjectId、AcDbHandle与AcDbStub之间的关系 详细描述了三者之间的关系
资源推荐
资源详情
资源评论
AcDbObjectId、AcDbHandle 与 AcDbStub 之间的关系 阿门原创 2010 年 04 月 01 日 星期四 下
午 4:57 近期,由于项目的需要做一套撤销恢复机制,特地研究了一下 AutoCAD(下文称为
ACAD)的撤销恢复机制,ACAD 的撤销和恢复是无限次的,也是就说,只要是同在一个会
话(打开到关闭的一个过程)中的操作你都可以撤销到原来的状态或者是重做刚才被撤销
的状态。而要实现整个一套机制的基础就包涵了所要说的三个主人公了。这篇文件就用来
说明这三者之间的关系。
从 ACAD R13 Release 版本起,为了处理数据库对象在内存生存周期而设计了一套方案。这
个方案为每一个对象都引用了两个部分的内容。第一部分,就是数据库对象本身,它是能
够常驻内存并且,如果内存需要释放的话它也能被换页到磁盘上,第二部分是一个叫做桩
(stub)的对象(AcDbStub 类),这个对象是常驻内存的,并且担当着数据库对象入口的
职责,当然,AcDbStub 只是一个很小的对象。这么一来,也就是说,如果 ACAD 系统需要
回收内存,第一部分是可以被回收的,但第二部分是不允许回收的(当前系统动态数据中
与原数据库对象的唯一协议),这个可以理解成一种代理节点的机制。
当一个对象或者是实体加入数据库时,系统将自动为其建立一个 AcDbStub 对象,并将其指
向到这个节点,然后再加入 AcDbStub 和被加入的对象或实体到数据库。而这个 AcDbStub
对象的内存地址就被当作是这个对象或实体的 ads_name 和 AcDbObjectId 了。同样的机制
也应用在数据库从磁盘读入内存的时候。所以这也就是为什么 ads_name 与 AcDbObjectId
的能够提供转换接口的原因了,因为它们本来就是一种东东。我们还可以看到更深一点,
就是当一个节点从数据库加载到内存时,它所对应的 AcDbStub 对象肯定是先于它本身来加
载的。这样才能使这一套机制正确的执行下去。(AcDbStub 对象也是需要编档的哦,当然
这一部分工作是系统本身来做)。
当一个数据库对象被打开时,ObjectARX 应用程序使用数据库对象的 objectId 传入
open 接口,然后返回真正的数据库对象的指针。事实是怎么进行的呢?那就是这个
objectId 就是这个数据库对象所对应的 AcDbStub 对象在内存中的地址(这个可以证明,这
个调用开始前,这个 AcDbStub 对象肯定已经被加载到内存),然后通过这个桩就可以得到
真正需要得到的数据库对象的指针。如果此时这个数据库对象已经被卸载掉(从内存中移
除),系统机制会把这个对象重新加载然后 AcDbStub 指向这个对象的新地址。
因此,一个 AcDbObjectId 对象是一个包括着真正数据库对象所对应的桩的地址的容器。
并且,它是一个非常重要的对象,因为它是一个会话过程中数据库节点的分配唯一的标识
的机制(这样处理确保其在一个会话过程中不会重复,你有没有见过,同一个内存地址包
括两个对象啊?)。
很多情况下,有可能用户定义了一些自定义对象或者是自定义实体,并且在其中需要
编档一些其它节点的 objectId,这是允许的(如果你写过自定义对象和自定义实体,你就知
道用得很广泛),因为,在编档的时候,这套机制会自动把 objectId 转换成对应数据库对
象的句柄(AcDbHandle),所以,它们通常能够在不同地会话过程中识别为同一个对象或实
体,因为 objectId 是会话时期唯一的(内存地址嘛),而句柄是数据库唯一的,所以,只
要确实转换正确,就能够跨会话来标识为同一个数据库对象,这样,下一个会话再使用的
时候,节点之间的关系是正确保存了也能够正确给读进来的。当编档对象的 objectId 的时
候,要明确的编档成为正确的关系类型(AcDbHardPointerId, AcDbSo&OwnershipId 等等),
资源评论
可爱的大磊子
- 粉丝: 0
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功