找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

楼主: 革天明

[求助] 模态对话框下读写用户字典,CAD直接崩溃,请教如何解决

[复制链接]

已领礼包: 112个

财富等级: 日进斗金

 楼主| 发表于 2016-10-13 13:06:56 | 显示全部楼层

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

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2016-10-13 13:22:54 | 显示全部楼层

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

使用道具 举报

已领礼包: 112个

财富等级: 日进斗金

 楼主| 发表于 2016-10-14 09:58:17 | 显示全部楼层
大家加把劲,卡在这里了,发现问题是只要读一次字典,然后再写入字典就会出错,或者是写入字典,再读取也出错,也就是说读写只能一次
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 8121个

财富等级: 富甲天下

发表于 2016-10-17 10:16:29 | 显示全部楼层
确保每个地方的指针不为空或者有效,譬如pDict如果为空或者无效的话,pDict->setAt(recName, pXrec, xrecObjId); 之类的语句就可能引起崩溃。
Objectarx编程引起的崩溃问题大多数是指针的问题。
建议用智能指针。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

发表于 2016-10-20 15:32:06 | 显示全部楼层


  1. void CCreateEnt::addNameDict(CString appName,CString recName,CString data)
  2. {
  3.         ErrorStatus es;
  4.         //得到命名对象词典指针
  5.          
  6.         AcDbDictionaryPointer pNamedobj(acdbHostApplicationServices()->workingDatabase()->namedObjectsDictionaryId(),AcDb::kForRead);
  7.   
  8.         // 检查是否已有关键字为“设计信息”的词典,如没有,则创建

  9.         AcDbObjectId dictId;
  10.         if (!pNamedobj->has(appName))
  11.         {
  12.                 pNamedobj->upgradeOpen();
  13.             AcDbDictionary*        pNewDict = new AcDbDictionary();               
  14.                 es=pNamedobj->setAt(appName, pNewDict, dictId);
  15.                 pNewDict->close();
  16.                 if (es!=Acad::eOk)
  17.                 {                       
  18.                         return;
  19.                 }
  20.         }
  21.         else
  22.         {
  23.                 pNamedobj->getAt(appName,dictId);
  24.         }
  25.         AcDbDictionaryPointer pDict(dictId,AcDb::kForRead);
  26.     AcDbObjectId xrecObjId;
  27.         if (!pDict->has(recName))
  28.         {
  29.                 pDict->upgradeOpen();
  30.             AcDbXrecord*        pNewXrec = new AcDbXrecord;               
  31.                 es=pDict->setAt(recName, pNewXrec, xrecObjId);         
  32.                 pNewXrec->close();
  33.                 if (es!=Acad::eOk)
  34.                 {
  35.                         return;
  36.                 }
  37.         }
  38.         else
  39.         {
  40.                 pDict->getAt(recName,xrecObjId);
  41.         }

  42.        
  43.         AcDbObjectPointer<AcDbXrecord> pXrec(xrecObjId,AcDb::kForWrite);
  44.          
  45.         struct resbuf *pHead;
  46.         pHead = acutBuildList(AcDb::kDxfText, data,0);
  47.         // 为AcDbXrecord对象设置链表
  48.         pXrec->setFromRbChain(*pHead);
  49.         acutRelRb(pHead);
  50.         pXrec->close();                 
  51. }

  52. void CCreateEnt::getNameDict(CString appName,CString recName,CString& data)
  53. {
  54.         AcDbDictionaryPointer pNamedobj(acdbHostApplicationServices()->workingDatabase()->namedObjectsDictionaryId(),AcDb::kForRead);
  55.         //得到关键字为"设计信息"的词典       
  56.     if (!pNamedobj->has(appName))
  57.     {                 
  58.                 acutPrintf(_T("\n未找到用户字典!"));
  59.                 return;
  60.     }         
  61.         AcDbObjectId dictId,xrecId;
  62.         pNamedobj->getAt(appName,dictId);
  63.         AcDbDictionaryPointer pNod(dictId,AcDb::kForRead);
  64.         if (!pNod->has(recName))
  65.         {
  66.                 acutPrintf(_T("\n未找到指定记录!"));
  67.                 return;
  68.         }
  69.         //得到关键字为"设计者"的AcDbXrecord对象
  70.         pNod->getAt(recName,xrecId);
  71.         AcDbObjectPointer<AcDbXrecord> pXrec(xrecId,AcDb::kForRead);
  72.          
  73.         struct resbuf *pRbList;
  74.         pXrec->rbChain(&pRbList);
  75.         pXrec->close();

  76.         if(pRbList!=NULL)
  77.         {
  78.                 data=pRbList->resval.rstring;
  79.         }
  80.         else
  81.         {
  82.                 acutPrintf(_T("\n未找到用户字典!"));
  83.         }
  84.         acutRelRb(pRbList);
  85. }
复制代码

点评

谢谢指导!我在高飞鸟的指导指导下找到原因为在没有找到字典时,return前没有关闭字典造成的崩溃  发表于 2016-10-20 19:18
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 13个

财富等级: 恭喜发财

发表于 2016-10-20 16:55:25 | 显示全部楼层

智能指针解决的是忘记关闭对象的问题,不是解决编程习惯不好,不判断返回值进行操作造成的错误。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 112个

财富等级: 日进斗金

 楼主| 发表于 2016-10-20 19:20:28 | 显示全部楼层

  • if (!pNamedobj->has(appName))
  •     {
  •                 pNamedobj->close();    
  •                 acutPrintf(_T("\n未找到用户字典!"));
  •                 return;
  •     }
重点为return前的关闭

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

使用道具 举报

已领礼包: 13个

财富等级: 恭喜发财

发表于 2016-10-20 19:26:23 | 显示全部楼层

楼主的例子很好,说明一个事,对象打开后,最近的不需要的地方就关闭它。一个对象要打开前写操作,另外的对象一定要关闭,哪怕是父容器。这个例子用智能指针也不行,因为在生存期内,智能指针不会析构。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 13个

财富等级: 恭喜发财

发表于 2016-10-20 19:28:53 | 显示全部楼层

我看错了,这个地方可以用智能指针,因为return前。

没仔细看楼主的代码,楼主,你要操作的辞典没有吗? 什么情况下执行到这个地方?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 112个

财富等级: 日进斗金

 楼主| 发表于 2016-10-20 19:35:15 | 显示全部楼层

//向图形数据库添加一个有名字典并添加记录
void CCreatEnt::YTMaddNameDict(CString appName,CString recName,CString data)
{
        // 锁定当前文档
        //acDocManager->lockDocument(acDocManager->curDocument(), AcAp::kWrite, NULL, NULL, true);
        //得到命名对象词典指针
        AcDbDictionary *pNamedobj, *pDict;
        Acad::ErrorStatus es=acdbHostApplicationServices()->workingDatabase()->getNamedObjectsDictionary(pNamedobj, AcDb::kForWrite);
        if(es!=Acad::eOk)
        {
                //文档解锁
                acDocManager->unlockDocument(acDocManager->curDocument());
        }
        // 检查是否已有关键字为“设计信息”的词典,如没有,则创建
        if (pNamedobj->getAt(appName, (AcDbObject*&) pDict,AcDb::kForWrite) == Acad::eKeyNotFound)
        {
                pDict = new AcDbDictionary;
                AcDbObjectId DictId;
                pNamedobj->setAt(appName, pDict, DictId);
        }
        if(pNamedobj!=NULL)
        {
                pNamedobj->close();
        }       
        //创建AcDbXrecord对象,并添加到扩展词典
        AcDbXrecord *pXrec = new AcDbXrecord;
        AcDbObjectId xrecObjId;
        pDict->setAt(recName, pXrec, xrecObjId);
        if(pDict!=NULL)
        {
                pDict->close();
        }       
        //为AcDbXrecord对象创建resbuf链表
        struct resbuf *pHead;
        pHead = acutBuildList(AcDb::kDxfText,data,RTNONE);
        // 为AcDbXrecord对象设置链表
        pXrec->setFromRbChain(*pHead);
        acutRelRb(pHead);
        if(pXrec!=NULL)
        {
                pXrec->close();
        }
        // 运行完解锁文档
        //acDocManager->unlockDocument(acDocManager->curDocument());
}
//从图形数据库获取一个有名字典并获取记录
void CCreatEnt::YTMgetNameDict(CString appName,CString recName,CString& data)
{
        AcDbDictionary *pNamedobj;
        Acad::ErrorStatus es=acdbHostApplicationServices()->workingDatabase()->getNamedObjectsDictionary(pNamedobj, AcDb::kForRead);
        if(es!=Acad::eOk)
        {
                //文档解锁
                acDocManager->unlockDocument(acDocManager->curDocument());
        }
        //得到关键字为"设计信息"的词典
        AcDbDictionary *pDict;
        if(pNamedobj->getAt(appName, (AcDbObject*&)pDict,AcDb::kForRead)== Acad::eKeyNotFound)
        {
                pNamedobj->close();
                acutPrintf(_T("\n未找到用户字典!"));
                return;
        }
        if(pNamedobj!=NULL)
        {
                pNamedobj->close();
        }       
        //得到关键字为"设计者"的AcDbXrecord对象
        AcDbXrecord *pXrec;
        if(pDict->getAt(recName, (AcDbObject*&) pXrec,AcDb::kForRead)== Acad::eKeyNotFound)
        {
                pDict->close();
                acutPrintf(_T("\n未找到指定记录!"));
                return;
        }
        if(pDict!=NULL)
        {
                pDict->close();
        }       
        struct resbuf *pRbList;
        pXrec->rbChain(&pRbList);
        if(pXrec!=NULL)
        {
                pXrec->close();
        }       
        //返回的结果缓存的处理参考示例工程
        //vector<CString> secret;
        //acutPrintf(_T("\n%s"),pRbList->resval.rstring);
        //vecStr.push_back(pRbList->resval.rstring);
        if(pRbList!=NULL)
        {
                data=pRbList->resval.rstring;
        }
        else
        {
                acutPrintf(_T("\n未找到用户字典!"));
        }
        acutRelRb(pRbList);
}

以上代码为我最终使用的代码,没有用智能指针,当前代码未再出现崩溃的情况,多谢@Highflybird的悉心指点!
程序主要的思路是打开一个dwg时,检查有无数据(保存在命名字典中),若有的话读取此数据,然后……当程序结束时,无论数据是否修改,还保存到对应的字典项中(新建或覆盖)

评分

参与人数 1D豆 +6 收起 理由
LoveArx + 6 有始有终奖!

查看全部评分

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-28 01:00 , Processed in 0.252970 second(s), 46 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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