Ошибка при getViewportArray

Автор Тема: Ошибка при getViewportArray  (Прочитано 8764 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн ДмитрийАвтор темы

  • ADN OPEN
  • Сообщений: 15
  • Карма: 0
Ошибка при getViewportArray
« : 18-01-2014, 15:42:02 »
   Подскажите, что не так, при удалении объекта возвращаемого getViewportArray возникает ошибка здесь:

        acarray.h:
Код - C++ [Выбрать]
  1.         template <class T, class R>
  2.         AcArray<T,R>::~AcArray()
  3.         {
  4.               if (mpArray != NULL)
  5.                  delete[] mpArray;
  6.          }

        В данном исходнике ошибка происходит в месте указанном стрелкой, если просто присвоить результат объекту AcDbObjectIdArray, то при выходе из блока {}, т.е. при вызове деструктора.

        Исходник:
Код - C++ [Выбрать]
  1.         /*Открываем шаблон*/
  2.         AcDbDatabase *pConturDB = new AcDbDatabase(Adesk::kFalse);
  3.         pConturDB->readDwgFile(szConturTemplateName , _SH_DENYNO);  
  4.  
  5.         /*Получаем все контуры*/
  6.         AcDbObjectIdArray ObjIDArray = GetContursByLayer(_T(OBJ_LAYER));//Массив выгружаемых данных
  7.         AcGePoint3d  pt (0.,0.,0.) ;
  8.         /*И переносим их на шаблон*/
  9.         acdbHostApplicationServices()->workingDatabase()->wblock(pConturDB, ObjIDArray, pt ,AcDb::kDrcIgnore);
  10.  
  11.  
  12.  
  13.         /*Центруем шаблон и выставляем масштаб*/
  14.  
  15.         /*Указатель на оригинальную базу (файл)*/
  16.         AcDbDatabase *pOriginDB  = acdbHostApplicationServices()->workingDatabase();
  17.  
  18.         acdbHostApplicationServices()->setWorkingDatabase(pConturDB);
  19.  
  20.         AcDbBlockTable * ConturBlockTable;
  21.         pConturDB->getBlockTable(ConturBlockTable , AcDb::kForWrite);
  22.         AcDbBlockTableIterator *ConturBlockTableIterator;
  23.         ConturBlockTable->newIterator(ConturBlockTableIterator , true , true);
  24.         for (ConturBlockTableIterator->start(); !ConturBlockTableIterator->done(); ConturBlockTableIterator->step())
  25.         {
  26.                 AcDbBlockTableRecord *ConturBlockTableRecord;
  27.                 ConturBlockTableIterator->getRecord(ConturBlockTableRecord,AcDb::kForWrite);
  28.                 if(ConturBlockTableRecord->isLayout() != Adesk::kFalse)
  29.                 {
  30.                         AcDbObjectId idLayout = ConturBlockTableRecord->getLayoutId();
  31.                         AcDbLayout * pLayout;
  32.                         acdbOpenObject(pLayout,idLayout,AcDb::kForRead);
  33.                         ACHAR *pLayName;
  34.                         pLayout->getLayoutName(pLayName);
  35.                         if(wstring(pLayName) == wstring(_T("Схема")))
  36.                         {
  37.                                 AcDbObjectIdArray ViewPortIdArray;
  38.                                 ViewPortIdArray.append(pLayout->getViewportArray());// <------- Вот здесь ошибка
  39.                                 AcDbObjectId ViewPortId = ViewPortIdArray.at(1);//Тест
  40.                         }
  41.                 }
  42.         }
  43.         acdbHostApplicationServices()->setWorkingDatabase(pOriginDB);
  44.  
  45.         /*Сохраним результат*/
  46.         pConturDB->saveAs(sConturFileName.GetBuffer());
  47.        
  48.  
  49.         delete pConturDB;

Добавил теги [code=cpp] ... [/code] чтобы код можно было нормально читать. Александр Ривилис
« Последнее редактирование: 18-01-2014, 19:32:36 от Александр Ривилис »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Ошибка при getViewportArray
« Ответ #1 : 18-01-2014, 19:42:31 »
Почему именно в этом месте происходит ошибка - я не знаю. Но знаю, что код выглядит очень (!!!) небрежным:
1. Почему все, что открывается нигде не закрывается? Я имею в виду ConturBlockTable, ConturBlockTableIterator, ConturBlockTableRecord, pLayout ...
2. Почему все эти объекты открываются для записи, если в действительности требуется только чтение?
3. Почему нигде в коде нет проверок на коды ошибок и на ненулевые значения указателей?
Чтобы я мог убедится, что ошибка в действительности имеет место нужно:
1. Сделать тестовый проект (без ничего лишнего), на котором эта ошибка воспроизводится однозначно и исправлены замеченные мной выше ошибки.
2. Приложить архив этого проекта вместе с тестовым чертежом (шаблоном) к соообщению
Только в этом случае можно однозначно сказать ошибка ли это в твоем коде, баг ли это ObjectARX/AutoCAD (и соотвественно нужно указать версию) и если это баг, то как можно его обойти.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДмитрийАвтор темы

  • ADN OPEN
  • Сообщений: 15
  • Карма: 0
Re: Ошибка при getViewportArray
« Ответ #2 : 19-01-2014, 15:40:59 »
Код в таком виде потому что в процессе отладки удалялось "всё лишнее", оставляя только "суть"))). Ниже привожу "нормальный" код, но тоже только по сути. Так же прилагаю проект в котором тестирую: MS VS 2010, Acad 2014. Если запускать, то в конфигурации Debug, т.к. в настройках релиза остались зависимости от дополнительных с торонних библиотек. Для работы файл ConturBuildingTemplate.dwg надо скопировать в "D:\", в автокаде команда SHEMA. Проверяю при открытом файле ТеррПлан_КПТ_В3ВсеЗоны(рабочий).dwg;

Код - C++ [Выбрать]
  1. void ExportGraphs(TCHAR * path)
  2. {
  3.         wchar_t szConturTemplateName[MAX_PATH];
  4.        
  5.         wcscpy(szConturTemplateName , _T("d:\\ConturBuildingTemplate.dwg"));
  6.        
  7.         /*Чертеж контура объекта*/
  8.         AcDbDatabase *pConturDB = new AcDbDatabase(Adesk::kFalse);
  9.         if(Acad::eOk != pConturDB->readDwgFile(szConturTemplateName , _SH_DENYNO))
  10.         {
  11.                 delete pConturDB;
  12.                 acutPrintf(_T("Ошибка при открытии шаблона\n"));
  13.                 return;
  14.         }
  15.  
  16.         /*Указатель на оригинальную базу (файл)*/
  17.         AcDbDatabase *pOriginDB  = acdbHostApplicationServices()->workingDatabase();
  18.        
  19.         /*Центруем шаблон и выставляем масштаб*/
  20.         acdbHostApplicationServices()->setWorkingDatabase(pConturDB);
  21.  
  22.         AcDbBlockTable * ConturBlockTable;
  23.         if(Acad::eOk != pConturDB->getBlockTable(ConturBlockTable , AcDb::kForRead))
  24.         {
  25.                 delete pConturDB;
  26.                 acutPrintf(_T("Ошибка при getBlockTable\n"));
  27.                 return;
  28.         }
  29.  
  30.         AcDbBlockTableIterator *ConturBlockTableIterator;
  31.         if(Acad::eOk != ConturBlockTable->newIterator(ConturBlockTableIterator , true , true))
  32.         {
  33.                 ConturBlockTable->close();
  34.                 delete pConturDB;
  35.                 acutPrintf(_T("Ошибка при newIterator\n"));
  36.                 return;
  37.         }
  38.        
  39.         for (ConturBlockTableIterator->start(); !ConturBlockTableIterator->done(); ConturBlockTableIterator->step())
  40.         {
  41.                 AcDbBlockTableRecord *ConturBlockTableRecord;
  42.  
  43.                 if(Acad::eOk != ConturBlockTableIterator->getRecord(ConturBlockTableRecord,AcDb::kForRead))
  44.                 {
  45.                         delete ConturBlockTableIterator;
  46.                         ConturBlockTable->close();
  47.                         delete pConturDB;
  48.                         acutPrintf(_T("Ошибка при ConturBlockTableIterator->getRecord\n"));
  49.                         return;
  50.                 }
  51.  
  52.                 if(ConturBlockTableRecord->isLayout() != Adesk::kFalse)
  53.                 {
  54.                         AcDbObjectId idLayout = ConturBlockTableRecord->getLayoutId();
  55.                         AcDbLayout * pLayout;
  56.                         if(Acad::eOk != acdbOpenObject(pLayout,idLayout,AcDb::kForRead))
  57.                         {
  58.                                 ConturBlockTableRecord->close();
  59.                                 delete ConturBlockTableIterator;
  60.                                 ConturBlockTable->close();
  61.                                 delete pConturDB;
  62.                                 acutPrintf(_T("Ошибка при acdbOpenObject\n"));
  63.                                 return;
  64.                         }
  65.  
  66.                         ACHAR *pLayName;
  67.                         pLayout->getLayoutName(pLayName);
  68.                         if(wstring(pLayName) == wstring(_T("Схема")))
  69.                         {
  70.                                 AcDbObjectIdArray ViewPortIdArray;
  71.                                 ViewPortIdArray.append(pLayout->getViewportArray());
  72.                                 AcDbObjectId ViewPortId = ViewPortIdArray.at(0);
  73.                         }
  74.                         pLayout->close();
  75.                 }
  76.  
  77.                 ConturBlockTableRecord->close();
  78.         }
  79.  
  80.         delete ConturBlockTableIterator;
  81.         ConturBlockTable->close();
  82.  
  83.         acdbHostApplicationServices()->setWorkingDatabase(pOriginDB);
  84.  
  85.        
  86.         /*Формируем имя результирующего файла*/
  87.         wstring wsConturFileName(path);
  88.         wsConturFileName.append(_T("\\contur.dwg"));
  89.         CString sConturFileName(wsConturFileName.c_str());
  90.        
  91.         /*Сохраним результат*/
  92.         pConturDB->saveAs(sConturFileName.GetBuffer());
  93.        
  94.         delete pConturDB;
  95. }

[вложение удалено администратором]

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Ошибка при getViewportArray
« Ответ #3 : 20-01-2014, 14:01:25 »
А ты не обратил внимание, что AutoCAD не хочет грузить твоё приложение - говорит, что оно не совместимо с AutoCAD, хотя потом и позволяет его загрузить? Очень зря, что не обратил внимание. В этом и была проблема. У тебя был установлен Platform Toolset в v90 и соотвественно брались Runtime-библиотеки предыдущей версии VS. Не зря же тебе пришлось добавлять msvcm90.dll, msvcp90.dll, msvcr90.dll. Так что считай что память распределяли библиотеки v100, а освобождали v90, что и приводило к ошибке.
Короче говоря поменяй везде Platform Toolset на v100 (придется еще слегка подправить stdafx.h, как я это сделал) и будет всё нормально. Во вложении исправленный проект. Всё лишнее я оттуда удалил.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДмитрийАвтор темы

  • ADN OPEN
  • Сообщений: 15
  • Карма: 0
Re: Ошибка при getViewportArray
« Ответ #4 : 20-01-2014, 16:20:05 »
Спасибо огромное. Проблема решена)))

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Ошибка при getViewportArray
« Ответ #5 : 20-01-2014, 16:20:42 »
Рад был помочь!
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн SatanaXIII

  • ADN OPEN
  • Сообщений: 27
  • Карма: 2
Re: Ошибка при getViewportArray
« Ответ #6 : 04-12-2015, 14:17:27 »
Короче говоря поменяй везде Platform Toolset на v100 (придется еще слегка подправить stdafx.h, как я это сделал)
Через настройки проекта можно поменять Platform Toolset:
Project->Properties->Configuration Properties->General->Platform toolset = Visual Studio 2010(v100)
Бензопила пилит тело, а виолончель душу.