lethuongtri 发表于 2022-2-21 09:13:36

Autocad在运行ArxCommand时崩溃

大家好,我正在学习ObjectArx,我有一个问题。下面是我将多个实体的图层转换成目标实体的图层的练习,当我运行命令时。几秒钟后,autocad(mechanical 2020)崩溃了。你能告诉我我的代码哪里错了吗?预先感谢!    void change layer(ads _ name ent name)。
{。
resbuf * entList。
resbuf * tranvRb。
TCHAR层名= { 0 };。

ent list = acdbEntGet(ent name);。
if (entList == NULL)。
{。
acutPrintf(_ T(" \ n无法获取实体的信息,命令结束!"));。
返回;。
}。

tranvRb = entList。

while (tranvRb)。
{。
开关(tranvRb->restype)。
{。
案例8:。
_tcscpy(layerName,tran vrb-> RES val . rst ring);。
break。
}。
tran vrb = tran vrb-> Rb next;。
}。

acutRelRb(entList);。
acutPrintf(_ T(" \ n目标的层名:%s "),layer name);。
ads_name ss,ssEntname。
Adesk::int 32 ss length;。
int rc。

RC = acedsget(NULL,NULL,NULL,NULL,ss);。
if (rc!= RTNORM)。
{。
acutPrintf(_ T(" \ n无法获取selectionset,命令结束!”));。
返回;。
}。

rc = acedSSLength(ss,& ss length);。
if (rc!= RTNORM)。
{。
acutPrintf(_ T(" \ n无法获取selectionset的计数,命令结束!"));。
返回;。
}。

for(Adesk::int 32 I = 0;i 。
{。
RC = acedsname(ss,I,ssent name);。
if (rc!= RTNORM)。
{。
break。
}。
ent list = acdbEntGet(ssent name);。
if (entList == NULL)。
{。
break。
}。
tranvRb = entList。
while (tranvRb)。
{。
开关(tranvRb->restype)。
{。
案例8:。
_ TCS cpy(tran vrb-> RES val . rst ring,layer name);。
break。
/*默认值:。
break*/。
}。
tran vrb = tran vrb-> Rb next;。
}。
RC = acdbEntMod(ent list);。
if (rc!= RTNORM)。
{。
acutPrintf(_ T(" \ n无法修改实体"));。
}。
acutRelRb(entList);。
}。
acedss free(ss);。
}。

无效。
cmdS2CL()。
{。
ads _ name entname。
ads _ point pt。
int rc。

RC = acedEntSel(_ T(" \ n选择目标实体:"),entname,pt);。
if (rc!= RTNORM)。
{。
acutPrintf(_ T(" \ n无法获取目标实体,命令结束!”));。
返回;。
}。
change layer(ent name);。
}。







**** Hidden Message *****

lethuongtri 发表于 2022-2-21 17:47:58

乍一看,我看到的唯一潜在问题是layerName缓冲区很小,考虑使用_tcscpy_s over _tcscpy
BTY,这种编码风格类似于您在旧式广告中的做法。使用AcDbEntity的方法
AcDbEntity::set layer(AcDbObjectId,Adesk::Boolean,bool)或AcDbEntity::setLayer (ACHAR*,Adesk::Boolean,bool)有更好、更现代的方法来实现这一点

lethuongtri 发表于 2022-2-23 09:29:04

谢谢你的回复,我用_tcscpy_s试过,但没有用。不管怎样,我用你的推荐尝试了另一种方法。然后它工作了!下面的代码还可以吗?还有什么需要改进的吗?提前感谢!.....................。
for(Adesk::Int32 i=0; i。
{。

rc=acedSSName(ss, i, ssEntname);。
如果(rc!=RTNORM)。
{。
休息;。
}。

AcDbObjectId旧;。
Acad::Errorstatus er;。

er=acdbGetObjectId(old, ssEntname);。
if(er!=Acad::eOk)。
{。
休息;。
}。

AcDbEntity*pEnt;。

er=acdbOpenObject(pEnt, old,AcDb::kForWrit);。
if(er!=Acad::eOk)。
{。
休息;。
}。

er=pEnt->setLayer(layerName);。
if(er!=Acad::eOk)。
{。
acutPrintf(_T("\n无法将图层设置为目标图层!"));。
}。

pEnt->关闭();。
}。
.................................。

lethuongtri 发表于 2022-2-23 18:17:56

看起来不错!我建议尝试使用智能指针,这样您就不必记住关闭实体。您还可以使用acadErrorStatusText来帮助找出方法可能失败的原因。
AcDbEntityPointer pEnt(oId,AcDb::kForWrite);。
if(pent . openstatus()= = eOk)。
{。
Acad::error status er = pEnt-> set layer(layer name);。
如果(呃!= Acad::eOk)。
{。
acutPrintf(_ T(" \ n无法将图层设置为目标图层' %ls '!"),acadErrorStatusText(er));。
}。
}。


//c++ 17。
if(AcDbEntityPointer pEnt(oId,AcDb::kForWrite);pEnt.openStatus() == eOk)。
{。
if(auto es = pEnt-> set layer(layer name);es!= Acad::eOk)。
{。
acutPrintf(_ T(" \ n无法将图层设置为目标图层' %ls '!")、acadErrorStatusText(es));。
}。
}。

lethuongtri 发表于 2022-2-24 06:18:00

感谢您的回复。我明白了,但是当我尝试您的代码时,我的视觉工作室显示
[标识符“acadErrorStatusText”未定义]
你能告诉我如何修复这个吗?
提前谢谢!

lethuongtri 发表于 2022-2-25 18:55:39


它可能不在机械API中,但尝试#include“acestext.h”

lethuongtri 发表于 2022-3-4 04:58:30

很抱歉最近回复了。我试过了,成功了!
非常感谢!
页: [1]
查看完整版本: Autocad在运行ArxCommand时崩溃