Тема: Проблема с формированием массива AcDbObjectIDArray

Многие функции требуют в качестве параметра такой массив. Мне нужно сформировать массив указателей на видовые экраны пространств листа чертежа.
Но непосредственно при вызове функции append AutoCAD выбрасывает. Что делать?
#include "mainfunctions.h"
Acad::ErrorStatus SetCurrentLayerFreezedInAllViewports (AcDbObjectId &layerId)
{Acad::ErrorStatus es;
AcDbDictionary *dLayouts;
AcDbDictionaryIterator *iLayout;
AcDbLayout *LLayout;
AcDbViewport *VViewport;
AcDbObjectId idLayout;
AcDbObjectId idLayout2;
AcDbObjectId idViewport;
AcDbObject* ObjLayout;
AcDbObjectIdArray *listLayers;
AcDbObjectIdArray *listViewports2;
AcDbObjectIdArray *listViewports;
AcDbBlockTable *tBlock;
AcDbBlockTableIterator *iBlock;
AcDbBlockTableRecord *rBlock;
  char *LayoutName;
char *LayoutName2;
char *BlockName;
bool TrFl;
acedAlert("Начинаем работать в теле функции!!!");
int i;
int j=0;
  if ((es=acdbHostApplicationServices ()->workingDatabase ()->getBlockTable(tBlock, AcDb::kForWrite))!=Acad::eOk)
{acedAlert("Не открылся таблица блоков!");}
tBlock->newIterator(iBlock,true,true);
  es=tBlock->newIterator(iBlock, true,true);
  //////////////////////////////////////// #1/////////////////////////////////////////////////////////////
  for (iBlock->start(); !iBlock->done(); iBlock->step())
{           
     if ((iBlock->getRecord(rBlock,AcDb::kForWrite)!=Acad::eOk)){acedAlert("Не получили запись из табл. блоков!");};              
     rBlock->getName(BlockName);
     acedAlert(BlockName);
     if ((rBlock->isLayout())!=Adesk::kFalse)
     {j=j+1;
            idLayout=rBlock->getLayoutId();
            if ((es=acdbOpenObject(LLayout,idLayout,AcDb::kForRead))!=Acad::eOk){acedAlert("Не открыли Layout!");};
            if ((es=LLayout->getLayoutName(LayoutName))!=Acad::eOk){acedAlert("Не взяли имя Layoutа!");};
                    if (j>1)
                    {   
                       
                        acedAlert(LayoutName);
                        listViewports.append(LLayout->getViewportArray());
                        acedAlert("Стоп 1");
                for (i=1;i<listViewports.length();i++)
                        {
                        idViewport=listViewports.at(i);
                        es=acdbOpenObject(VViewport,idViewport,AcDb::kForWrite);
                        if ((es=Acad::eOk)) {acedAlert("Открыли Viewport!!!!");}
                        }
                    }
         }
}           
delete iBlock;
tBlock->close();           
delete iLayout;
dLayouts->close();
acutPrintf("\nВроде, дошли до конца фунцции..............");
return(es);
}
P.S. Видел что в некоторых примерах вместо -> ставят точки при работе с массивами. А у меня не компилируется! Ставлю в этих местах вместо точек стрелочки - компилируется, но выбрасывает из АКАДа. Почему?
Заранее благодарю за помощь.

Re: Проблема с формированием массива AcDbObjectIDArray

Замени AcDbObjectIdArray *listViewports; на AcDbObjectIdArray listViewports; или AcDbObjectIdArray *listViewports = new AcDbObjectIdArray(); Ты работаешь с неинициализированным указателем!

Re: Проблема с формированием массива AcDbObjectIDArray

Большое спасибо

Re: Проблема с формированием массива AcDbObjectIDArray

> Зигмус
Кстати если будешь использовать AcDbObjectIdArray *listViewports = new AcDbObjectIdArray(); то не забывай делать delete listViewports; во избежании утечек памяти. Хотя в данном случае лучше размещать его в стеке, т.е. использовать AcDbObjectIdArray listViewports;

Re: Проблема с формированием массива AcDbObjectIDArray

Еще одна похожая проблема по той же теме и по тому же листингу:
Я получаю в функцию аргумент AcDbObjectId layerId.
Размещаю в стеке AcDbObjectIdArray listLayers;
Пытаюсь в этот массив запихнуть полученное значение. Вроде компиляция происходит, однако АвтоКад на этом этапе выкидывает.
Если задать массив указателей таким образом: AcDbObjectIdArray *listViewports = new AcDbObjectIdArray(); то не происходит компиляции, так как этот массив мне нужно передать функции if (((VViewport->isOn))){es=VViewport->freezeLayersInViewport(listLayers);};  а она отказывается в этом случае от предлагаемого ей типа аргумента.

#include "mainfunctions.h"
Acad::ErrorStatus SetCurrentLayerFreezedInAllViewports (AcDbObjectId layerId)
{Acad::ErrorStatus es;
// AcDbLayer LLayer;
 AcDbLayout *LLayout;
 AcDbViewport *VViewport;
 AcDbObjectId idLayout;
 AcDbObjectId idViewport;
 AcDbObjectIdArray listLayers2;
 AcDbObjectIdArray listLayers;
 AcDbObjectIdArray *listViewports = new AcDbObjectIdArray();
 AcDbBlockTable *tBlock;
 AcDbBlockTableIterator *iBlock;
 AcDbBlockTableRecord *rBlock;
 char *LayoutName;
  char *BlockName;
 Adesk::Boolean  TrFl;
 acedAlert("Начинаем работать в теле функции!!!");
int i;
int j=0;
listLayers.insertAt(1,layerId);
if ((listLayers.at(1))!=layerId){acedAlert("Где layerId?");};
 if ((es=acdbHostApplicationServices ()->workingDatabase ()->getBlockTable(tBlock, AcDb::kForWrite))!=Acad::eOk)
 {acedAlert("Не открылся таблица блоков!");}
 tBlock->newIterator(iBlock,true,true);
  es=tBlock->newIterator(iBlock, true,true);
  //////////////////////////////////////// #1/////////////////////////////////////////////////////////////
  for (iBlock->start(); !iBlock->done(); iBlock->step())
 {            
     if ((iBlock->getRecord(rBlock,AcDb::kForWrite)!=Acad::eOk)){acedAlert("Не получили запись из табл. блоков!");};               
     rBlock->getName(BlockName);
     acedAlert(BlockName);
     if ((rBlock->isLayout())!=Adesk::kFalse)
     {j=j+1;
            idLayout=rBlock->getLayoutId();
            if ((es=acdbOpenObject(LLayout,idLayout,AcDb::kForRead))!=Acad::eOk){acedAlert("Не открыли Layout!");};
            if ((es=LLayout->getLayoutName(LayoutName))!=Acad::eOk){acedAlert("Не взяли имя Layoutа!");};
                    if (j>1)
                    {
                    acedAlert(LayoutName);
                    listViewports->append(LLayout->getViewportArray());
                    acedAlert("Стоп 1");
                for (i=1;i<listViewports->length();i++)
                        {
                        idViewport=listViewports->at(i);
                        if ((es=acdbOpenObject(VViewport,idViewport,AcDb::kForWrite))==Acad::eOk) {acedAlert("Открыли Viewport!!!!");};
                        if (((VViewport->isOn))){es=VViewport->freezeLayersInViewport(listLayers);};
                            
                
                        }
                    }
         }
}            
delete iBlock;
rBlock->close();
tBlock->close();            
delete VViewport;
delete listViewports;
//delete listLayers;
acutPrintf("\nВроде, дошли до конца фунцции..............");
VViewport->close();
acedAlert("Конец функции!");
return(es);
}

Могли бы Вы дать совет и в этом случае?
И если можно, вкратце, в чем разница между описанными Вами способами задания, и чем *объект отличается от объект?

Re: Проблема с формированием массива AcDbObjectIDArray

и чем *объект отличается от объект?

Начните с нормального учебника по C++, где объясняется разница между объектом и указателем на него.
А пока мой вариант Вашего кода.

  static Acad::ErrorStatus SetCurrentLayerFreezedInAllViewports (AcDbObjectId  idLayer = acdbCurDwg()->clayer())
  {
    Acad::ErrorStatus es;
    AcDbObjectIdArray listLayouts;
    AcDbDictionary *pLayoutDictionary = NULL;
    AcDbObjectIdArray listLayers; listLayers.append(idLayer);
    if ((es = acdbCurDwg()->getLayoutDictionary(pLayoutDictionary,AcDb::kForRead)) != Acad::eOk)
      return es;
    AcDbDictionaryIterator *itLayout = pLayoutDictionary->newIterator();
    pLayoutDictionary->close();
    if (!itLayout) {
      pLayoutDictionary->close();  return Acad::eInvalidInput;
    }
    for (;!itLayout->done();itLayout->next()) {
      listLayouts.append(itLayout->objectId());
    }
    delete itLayout;
    for (int i = 0; i < listLayouts.length(); i++)
    {
      AcDbObjectPointer<AcDbLayout> pLayout(listLayouts[i],AcDb::kForRead);
      if ((es = pLayout.openStatus()) != Acad::eOk) return es;
      AcDbObjectIdArray listViewports = pLayout->getViewportArray();
      for (int j = 0; j < listViewports.length(); j++)  {
        AcDbObjectPointer<AcDbViewport> pViewport(listViewports[j],AcDb::kForWrite);
        if ((es = pViewport.openStatus()) != Acad::eOk) return es;
        es = pViewport->freezeLayersInViewport(listLayers);
        if (es != Acad::eOk) return es;
      }
    }
    return Acad::eOk;
  }