阿门原创 http://hi.baidu.com/lihao102     欢迎转载

近期,由于项目的需要做一套撤销恢复机制,特地研究了一下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, AcDbSoftOwnershipId等等),相信写过自定义实体的人都编过,呵呵,只有这个ObjectARX内部机制才能正确的将它们之前的关系正确的转向成句柄,并编档好。

如果你需要把一个对象正确的保存到一个扩展文件中(非dwg或dxf文件),这时你就不能使用objectId了(原因很简单,不能转换了啊,对象只有dwg和dxf的编档接口(可以看看AcDbObject类的接口)),因为,objectId的值在不同的会话中是不同的。可以使用的替代方案是,你必须保存这个数据库对象对应的句柄,跨会话就只能用数据库唯一的标识——句柄。如果你当前工作环境下有多个数据库文件(dwg文件),那么为了达到唯一标识一个对象的话,你必须保存好dwg文件名和对象对应的句柄了,因为,句柄只是在一个数据库中唯一,不同的数据库中,句柄是会重复的。

如果你知道一个句柄,那么你可以通过AcDbDatabase::getAcDbObjectId()来得到对应对句的objectId。为什么接口在AcDbDatabase上,这个很好理解吧,因为句柄才是数据库唯一的啊。

如果你知道对象的objectId想得到对象对应的句柄,你可以打开这个对象并且使用AcDbObject::getAcDbHandle()接口来获取,因为,objectId保存的内存地址对应的AcDbStub对象保存着对应的数据库对象的指针,而句柄是这个数据库对象上一个属性而已,所以 很容易就得到了。

由上面这些内容,可以想像得到,为数据库对象分配ID的机制就是使用了在同一会话中,不同节点加载的内存地址肯定是不同的这一原理和小技巧来实现的,而为数据库对象分配句柄的则是DWG数据库中实现的一套机制,很容易,句柄不就是一个64位值嘛,加一个节点累加一次就是了。 为了要灵活的管理内存,而使用了代理对象的这一个方案(AcDbStub对象)。

AcDbObjectId、AcDbHandle与AcDbStub之间的关系 阿门原创相关推荐

  1. Day-16 面向对象03 类与类之间的关系

    一.类与类之间的依赖关系 我用着你,但是你不属于我,这种关系是最弱的,比如,公司和雇员之间,对于正式员工,肯定要签订劳动合同,还得小心伺候着,但是如果是兼职,那无所谓,需要了你就来,不需要你就可以拜拜 ...

  2. 【linux】图形界面基础知识(X、X11、GNOME、Xorg、KDE的概念和它们之间的关系)

    转载自:https://blog.csdn.net/zhangxinrun/article/details/7332049 简介 LINUX初学者经常分不清楚linux和X之间,X和Xfree86之间 ...

  3. 嵌入式开发之信号采集同步---VSYNC和HSYNC的作用以及它们两者之间的关系

    VSYNC和HSYNC的作用以及它们两者之间的关系 VSYNC和HSYNC的作用以及它们两者之间的关系 VSYNC和HSYNC是什么 VSYNC: vertical synchronization,指 ...

  4. 通过构建城市来解释HTML,CSS和JavaScript之间的关系

    by Kevin Kononenko 凯文·科诺年科(Kevin Kononenko) 通过构建城市来解释HTML,CSS和JavaScript之间的关系 (The relationship betw ...

  5. Python中怎样改变集合之间的关系?

    Python中怎样改变集合之间的关系?数学中,两个集合关系的常见操作包括:交集.并集.差集.补集.设A,B是两个集合,集合关系的操作介绍如下: 交集是指属于集合A且属于集合B的元素所组成的集合, 并集 ...

  6. 当支持向量机遇上神经网络:这项研究揭示了SVM、GAN、Wasserstein距离之间的关系...

    选自arXiv 作者:Alexia Jolicoeur-Martineau 编辑:小舟.蛋酱 转载自公众号:机器之心 SVM 是机器学习领域的经典算法之一.如果将 SVM 推广到神经网络,会发生什么呢 ...

  7. https协议必须使用443端口吗_http、https、http2、websocket之间的关系

    http.https.http2.websocket之间的关系 http:目前绝大多数是http1.1版本,最原始的web协议,默认80端口,基于TCP协议. https:加密的http协议,默认44 ...

  8. android 如何获得activity的view对象,Android的Activity 、 Window 、 View之间的关系

    什么是Activity .View . Window? Activity:是Android 四大组件之一, 是存放View对象的容器,也是我们界面的载体,可以用来展示一个界面.它有一个SetConte ...

  9. 作为项目经理,如何处理好与不同类型客户之间的关系?

    作为项目经理,如何处理好与客户之间的关系非常重要.但是究竟如何处理客户关系呢?客户的人员都有哪些类型?不同类型的客户的应对是否都一样呢?下面我们来看看在日常工作中经常遇到的客户类型,应该如何处理跟他的 ...

最新文章

  1. 中国电子信息产业发展研究院主办的2018中国软件大会上大快搜索“又双叒叕”获奖了...
  2. 建立单链表(头插法)
  3. 荣获CHINA TOP cited paper award 2021的神经工程领域顶级期刊的论文汇总
  4. c语言大作业之镖行天下,天下识君--如何最快速度刷完天下识君
  5. 设计模式五:外观模式
  6. Python基础(6)_函数
  7. 多数据源使用spring-data-jpa无法部署到JBoss As Server
  8. python绝对值函数fabs_Python中abs()和math.fabs()区别
  9. 为什么我们没有选择Rust?
  10. python中将数组存储为二进制文件并读取
  11. Verilog中parameter(参数)与define(宏定义)的区别
  12. [翻译] FeSpinner
  13. Java性能调优全攻略来了
  14. Linux基础学习记录
  15. html 列表实现展开和收起,实现列表展开收起效果
  16. 知乎热议:科学网发布文章称「我国数学家证明 NP=P」,会带来怎样的影响?
  17. unity黑白滤镜_unity图像优化美化滤镜渲染插件Beautify 6.2.7
  18. 一些好用的链接(持续更新)——视频相关
  19. HTTP协议——面试专题
  20. 世界最具影响力的100个品牌

热门文章

  1. 《Linux防火墙(第4版)》——2.3 对一个数据包的驳回(Rejecting)VS拒绝(Denying)...
  2. 周大福ctf是什么意思_CTF是什么意思|周大福CTF2又是指的什么
  3. MAC 命令行解压 rar 文件
  4. 计算机硬件acc作用,详细为你解析什么是汽车ACC自适应巡航,有什么特点和作用...
  5. OpenCL编译方式技术分析
  6. oracle check更改,Oracle With Check Option
  7. 2022年ccpc桂林站
  8. 编写一个程序,把您的年龄转换成天数并显示二者的值。不用考虑平年( fractional year)和闰年(leapyear)的问题
  9. CentoS 7 LNMP 环境部署zabbix监控
  10. dedeCMS验证码不显示