Author Topic: Autocad became crash when run Arxcommand  (Read 1103 times)

0 Members and 1 Guest are viewing this topic.

lethuongtri

  • Mosquito
  • Posts: 10
Autocad became crash when run Arxcommand
« on: February 21, 2022, 09:13:36 AM »
Hello everybody. I 'm learning ObjectArx ,and i have a question .
the below is my practise to change multiple entities 's layer into target entity 's layer.
When i run command . After few second ,autocad(mechanical 2020) got crash.
Can you tell me where is wrong in my code.
Thanks in advance!

Code - C++: [Select]
  1. void changeLayer(ads_name entname)
  2. {
  3.     resbuf* entList;
  4.     resbuf* tranvRb;
  5.     TCHAR layerName[30] = { 0 };
  6.  
  7.     entList = acdbEntGet(entname);
  8.     if (entList == NULL)
  9.     {
  10.         acutPrintf(_T("\nCannot get entity 's infomation.Command ended!"));
  11.         return;
  12.     }
  13.    
  14.     tranvRb = entList;
  15.  
  16.     while (tranvRb)
  17.     {
  18.         switch (tranvRb->restype)
  19.         {
  20.         case 8:
  21.             _tcscpy(layerName, tranvRb->resval.rstring);
  22.             break;
  23.         }
  24.         tranvRb = tranvRb->rbnext;
  25.     }
  26.  
  27.     acutRelRb(entList);
  28.     acutPrintf(_T("\nTarget 's layer name:%s"), layerName);
  29.     ads_name ss,ssEntname;
  30.     Adesk::Int32 ssLength;
  31.     int rc;
  32.  
  33.     rc = acedSSGet(NULL, NULL, NULL, NULL, ss);
  34.     if (rc != RTNORM)
  35.     {
  36.         acutPrintf(_T("\nCannot get selectionset.Command ended!"));
  37.         return;
  38.     }
  39.  
  40.     rc = acedSSLength(ss, &ssLength);
  41.     if (rc != RTNORM)
  42.     {
  43.         acutPrintf(_T("\nCannot get selectionset 's count.Command ended!"));
  44.         return;
  45.     }
  46.  
  47.     for (Adesk::Int32 i = 0; i < ssLength; i++)
  48.     {
  49.         rc = acedSSName(ss, i, ssEntname);
  50.         if (rc != RTNORM)
  51.         {
  52.             break;
  53.         }
  54.         entList = acdbEntGet(ssEntname);
  55.         if (entList == NULL)
  56.         {
  57.             break;
  58.         }
  59.         tranvRb = entList;
  60.         while (tranvRb)
  61.         {
  62.             switch (tranvRb->restype)
  63.             {
  64.             case 8:
  65.                 _tcscpy(tranvRb->resval.rstring, layerName);
  66.                 break;
  67.             /*default:
  68.                 break;*/
  69.             }
  70.             tranvRb = tranvRb->rbnext;
  71.         }
  72.         rc = acdbEntMod(entList);
  73.         if (rc != RTNORM)
  74.         {
  75.             acutPrintf(_T("\nFailed to modify the entity"));
  76.         }
  77.         acutRelRb(entList);
  78.     }
  79.     acedSSFree(ss);
  80. }
  81.  
  82. void
  83. cmdS2CL()
  84. {
  85.     ads_name entname;
  86.     ads_point pt;
  87.     int rc;
  88.  
  89.     rc = acedEntSel(_T("\nSelect the target entity:"), entname, pt);
  90.     if (rc != RTNORM)
  91.     {
  92.         acutPrintf(_T("\nCannot get the target entity.Command ended!"));
  93.         return;
  94.     }
  95.     changeLayer(entname);
  96. }
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7283
  • AKA Daniel
Re: Autocad became crash when run Arxcommand
« Reply #1 on: February 21, 2022, 05:47:58 PM »
At first glance, the only potential issue I see is the layerName buffer is small, consider using _tcscpy_s over _tcscpy

BTY, this coding style is analog to how you would do this in old style ADS. There are better, more modern ways to do this using AcDbEntity’s methods

AcDbEntity::setLayer (AcDbObjectId, Adesk::Boolean, bool) or  AcDbEntity::setLayer (ACHAR*, Adesk::Boolean, bool)


Retired

lethuongtri

  • Mosquito
  • Posts: 10
Re: Autocad became crash when run Arxcommand
« Reply #2 on: February 23, 2022, 09:29:04 AM »
Thanks for your reply . I tried with _tcscpy_s but I didn't work.
anyway i tried another way with your recommendation .Then it work !
The below code is ok ? Is there something more to improve ?
Thanks in advance !

Code - C++: [Select]
  1. .....................
  2. for (Adesk::Int32 i = 0; i < ssLength; i++)
  3.     {
  4.        
  5.         rc = acedSSName(ss, i, ssEntname);
  6.         if (rc != RTNORM)
  7.         {
  8.             break;
  9.         }
  10.        
  11.         AcDbObjectId oId;
  12.         Acad::ErrorStatus er;
  13.  
  14.         er = acdbGetObjectId(oId, ssEntname);
  15.         if (er != Acad::eOk)
  16.         {
  17.             break;
  18.         }
  19.  
  20.         AcDbEntity* pEnt;
  21.        
  22.         er = acdbOpenObject(pEnt, oId, AcDb::kForWrite);
  23.         if (er != Acad::eOk)
  24.         {
  25.             break;
  26.         }
  27.  
  28.         er = pEnt->setLayer(layerName);
  29.         if (er != Acad::eOk)
  30.         {
  31.             acutPrintf(_T("\nCannot set layer to the target layer!"));
  32.         }
  33.  
  34.         pEnt->close();
  35.     }
  36. ...............................
  37.  
« Last Edit: February 23, 2022, 09:33:03 AM by lethuongtri »

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7283
  • AKA Daniel
Re: Autocad became crash when run Arxcommand
« Reply #3 on: February 23, 2022, 06:17:56 PM »
Looks good!

I recommend trying to use the smart pointers, so you don’t have to remember to close the entities.
also you can use acadErrorStatusText to help find out why a method might fail

Code - C: [Select]
  1.             //c++ 11
  2.             AcDbEntityPointer pEnt(oId, AcDb::kForWrite);
  3.             if (pEnt.openStatus() == eOk)
  4.             {
  5.                 Acad::ErrorStatus er = pEnt->setLayer(layerName);
  6.                 if (er != Acad::eOk)
  7.                 {
  8.                     acutPrintf(_T("\nCannot set layer to the target layer '%ls' !"), acadErrorStatusText(er));
  9.                 }
  10.             }
  11.  
  12.  
  13.             //c++ 17
  14.             if (AcDbEntityPointer pEnt(oId, AcDb::kForWrite); pEnt.openStatus() == eOk)
  15.             {
  16.                 if (auto es = pEnt->setLayer(layerName); es != Acad::eOk)
  17.                 {
  18.                     acutPrintf(_T("\nCannot set layer to the target layer '%ls' !"), acadErrorStatusText(es));
  19.                 }
  20.             }
  21.  
Retired

lethuongtri

  • Mosquito
  • Posts: 10
Re: Autocad became crash when run Arxcommand
« Reply #4 on: February 24, 2022, 06:18:00 AM »
Thanks for your reply .I got it but when i tried your code ,my visual studio show
[ identifier "acadErrorStatusText" is undefined ]
Can you tell me how to fix this ?
Thanks in advance !

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7283
  • AKA Daniel
Re: Autocad became crash when run Arxcommand
« Reply #5 on: February 25, 2022, 06:55:39 PM »
Thanks for your reply .I got it but when i tried your code ,my visual studio show
[ identifier "acadErrorStatusText" is undefined ]
Can you tell me how to fix this ?
Thanks in advance !

it may not be in the mechanical API, but try #include "acestext.h"
Retired

lethuongtri

  • Mosquito
  • Posts: 10
Re: Autocad became crash when run Arxcommand
« Reply #6 on: March 04, 2022, 04:58:30 AM »
Sorry for replying lately. I tried and it worked !

Thank you alot !