找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1557|回复: 10

[求助]:请问,谁知道如何清除一个实体上的扩展数据?

[复制链接]
发表于 2002-4-16 03:31:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
同上
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 145个

财富等级: 日进斗金

发表于 2002-4-16 05:58:23 | 显示全部楼层
下面是ARX和LISP的实现方法:


  1. void removeXdata()
  2. {
  3.     ads_name eNam;

  4. ads_point pt;

  5. int i = acedEntSel ("\nPick an object:", eNam, pt);



  6. if (RTNORM != i)

  7. {

  8. return;

  9. }

  10. AcDbObjectId ObjId;

  11. acdbGetObjectId(ObjId, eNam);

  12. AcDbEntity *pEnt;

  13. acdbOpenAcDbEntity(pEnt, ObjId, AcDb::kForWrite);

  14. resbuf *xdata = pEnt->xData(NULL);

  15. if (xdata)

  16. {

  17. xdata->rbnext = NULL;

  18. pEnt->setXData(xdata);

  19. acutRelRb(xdata);

  20. }

  21. pEnt->close();

  22. }
复制代码


下面是和上面等价的LISP实现:



  1. (defun c:DelXdata()
  2. (setq l (car (entsel "Pick object:")))
  3. (if l (progn
  4.      (redraw l 3)
  5.      (setq le (entget l '("*")) )
  6.      (setq xdata (assoc '-3 le))
  7.      (setq le
  8.            (subst (cons (car xdata) (list (list (car (car (cdr xdata))))))
  9. xdata le))
  10.      (entmod le)
  11.      (redraw l 4)
  12.      le
  13.     )
  14. )
  15. )


说明: 如果一个实体附着了多个应用程序名的扩展实体数据,把上面代码放到循环里面就可以了。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2002-4-16 06:58:09 | 显示全部楼层
(setq le
           (subst (cons (car xdata) (list (list (car (car (cdr xdata))))))
xdata le))

讲解一下这一段 :)
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2002-4-16 07:39:12 | 显示全部楼层
最初由 梦断江南 发布
[B](setq le
           (subst (cons (car xdata) (list (list (car (car (cdr xdata))))))
xdata le))

讲解一下这一段 :) [/B]


先说下删除XDATA的原理,XDATA的组成是祖码-3开始,然后是子表,如:

'(-3 子表1 子表2 ...子表n)

每一个子表是一个应用程序名标识的一组扩展实体数据。

如:'("应用程序名1" ....数据)

清除一个应用程序名为标识的扩展实体数据,把应用程序名后面的数据项清除,只保留应用程序名,然后更新实体数据,那么ACAD就会把只有应用程序名而没有数据的“一组扩展实体数据”的删除了。

举例:
(-3   ("ABC" (1070 . 2) (1070 . 3))
       ("DEF" (1070 . 3))
)

上面-3是扩展数据开始,"ABC","DEF"是两个应用程序名标识的两组扩展实体数据。那么我们要删除"ABC"把上面的表中的ABC子表变成("ABC"),然后把上面的表entmod就可以了。

下面看看上面的代码:
(setq le
(subst (cons (car xdata) (list (list (car (car (cdr xdata))))))
xdata le))

这个的结果就是把扩展实体数据的第一个应用程序名标识的子表变成:
(-3   ("ABC")
       ("DEF" (1070 . 3))
)

然后(entmod le)就会更新实体的数据的,ABC扩展数据就没有了。

所以,上面的LISP的作用是把第一个扩展实体数据删除。

因此若要删除所有的扩展实体数据,循环执行下上面的代码部分就可以了。

另:若要删除“指定应用程序名”的扩展实体数据,按照上面的原理,把那个应用程序名标识的子表按照上面的方法仅仅留下名字,去除数据即可。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-5-12 09:10:21 | 显示全部楼层
ads_name eNam;
ads_point pt;
int i = acedEntSel ("\nPick an object:", eNam, pt);
if (RTNORM != i)
{
  return;
}
AcDbObjectId ObjId;
acdbGetObjectId(ObjId, eNam);
AcDbEntity *pEnt;
acdbOpenAcDbEntity(pEnt, ObjId, AcDb::kForWrite);
resbuf *xdata = pEnt->xData(NULL);
while(xdata)
{
xdata->rbnext = NULL;
pEnt->setXData(xdata);
acutRelRb(xdata);
xdata = pEnt->xData(NULL);
}
pEnt->close();
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-5-12 10:14:32 | 显示全部楼层
清除一个实体上的扩展数据有什么用途?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-5-12 23:08:09 | 显示全部楼层
(2楼) and (5楼) 's ARX-program may cause Memory Leak?

All  data_nodes at xdata->next  and afters are missing to free, becase
of PreSetting xdata->next=NULL before  Calling acutRelRb(xdata).
[/COLOR]
-----------------------------------------------------------------------

  1. ads_name eNam;
  2. ads_point pt;
  3. int i = acedEntSel ("\nPick an object:", eNam, pt);
  4. if (RTNORM != i)
  5. {
  6.     return;
  7. }
  8. AcDbObjectId ObjId;
  9. acdbGetObjectId(ObjId, eNam);
  10. AcDbEntity *pEnt;
  11. acdbOpenAcDbEntity(pEnt, ObjId, AcDb::kForWrite);
  12. resbuf *xdata = pEnt->xData(NULL);
  13. [COLOR=blue]
  14. resbuf  Tmp, *xp;
  15. Tmp.restype = 1001;
  16. Tmp.rbnext = NULL;
  17. for (xp = xdata; xp; xp = xp->rbnext)
  18. {
  19.     if (xp->restype == 1001)
  20.     {
  21.         Tmp.resval.rstring =  xp->resval.rstring;
  22.         pEnt->setXData (&Tmp);
  23.     }
  24. }
  25. [/COLOR]
  26. acutRelRb(xdata);
  27. pEnt->close();
复制代码


=======================
To :(  6楼楼主: 清除一个实体上的扩展数据有什么用途? )
--------------------
   Free unused-Xdata for more free-MEMORY.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-5-13 16:59:50 | 显示全部楼层
多谢7楼提到的,我以前在作者中的处理的时候,经常遇到Memory Leak的情况,以及解决的不是很好,对于AutoCAD得指针的处理,有没有比较规律性的东西来防止这个内存的泄漏!?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-5-16 13:30:33 | 显示全部楼层
我在上面7楼提到的那个程序内存泄漏问题,应该不难理解,它纯
粹是程序逻辑欠缺所致,在理解acutRelRb()功能、resbuf结构基础
上,认真检查程序,应该可以检查出来。
对于 ObjectARX里是否有 比较规律性的东西来防止内存的泄漏,
我比较茫然,迄今我所了解到的ARX中的内存处理有些混乱,在我
看到诸如下面的ARX 介绍,有点心惊肉跳:

  1. AcDbSymbolTableRecord::getName Function Acad::ErrorStatus

  2. getName(

  3. const char*& pName) const;

  4. pName Returns pointing to string that is the name of the SymbolTable record

  5. This function sets pName to point to the name string of the SymbolTableRecord.

  6. Warning As the const qualifier indicates, no attempt should be made to deallocate the returned string.

  7. The SymbolTableRecord name string is used for DXF group code 2.


  8. --------------------------------------------------------------------------------

  9. Acad::ErrorStatus

  10. getName(

  11. char*& pName) const;

  12. pName Returns pointing to string that is the name of the SymbolTable record

  13. This function returns a pointer to a string that is a dynamically allocated copy and needs to be freed by the calling application.

  14. The SymbolTableRecord name string is used for DXF group code 2.



这两个重载函数的定义,只是一个 const 的差异,却得到两个迥然
不同的结果,前者多了const而仅仅得到一个char * 的指针值而已,
后者却得到复制的char string 及其指针. 这里的介绍并不难理解,问
题在于,在程序普通检查中很难区别两者,很难检查出错误,除非
刻意对该问题作检查。

ARX 中得到的动态字符串如何清除? free(), acad_free(), delete[],
acutDelString(), 还是acdbFree() ? 如果知道其alloc 方式,当然容易知
道应该采用哪个free了,问题是ARX库的原码我们看不到,仅仅只
能凭 ARX 文档“肤浅"的介绍,去猜测。。。很累啊!这里所出现
的内存泄漏问题更难查!

   AutoCAD 2004的 ARX 要用 MSV 2002 编译,如果使用MSV
2003 编译,AutoCAD警告,可能会引起内存泄漏。对于这个问题,
除了无奈,大家还能做什么. MS真是该骂,仅仅一个版本,
在内存处理方面就会这样不兼容,恐怕这不是技术问题,而是”经
济“问题在作怪!

各位,对 ARX中的内存问题有何看法,也说说看。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-6-23 17:31:26 | 显示全部楼层
谢谢~~~
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-4-30 15:34:43 | 显示全部楼层
自己写个平台吧,呵呵,就什么都解决了。

顺便问一下,扩展数据怎么修改啊直接赋值就好了吗,应该不行吧,我修改了链表的值,然后
entityname->setXData(lineRb);
acutRelRb(lineRb);
再查看扩展数据时却没变。
难道还要删了。再重新加?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-15 08:28 , Processed in 0.243934 second(s), 51 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表