ARXDBG и MGDDBG - утилиты для анализа AutoCAD, чертежа и т.д.

Автор Тема: ARXDBG и MGDDBG - утилиты для анализа AutoCAD, чертежа и т.д.  (Прочитано 141555 раз)

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

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
MGDDBG в 2017 автокаде падает в фатал при наличии у объекта гиперссылки.

Взял вот этот самый живой форк и он, то же рушится.

Рушится он в классе MgdDbg.Snoop.Data.ObjectCollection
на 52 строке (28 строка на фрагменте):
Код - C# [Выбрать]
  1. m_val = new ArrayList(val);

Что бы не бегать, тут код этого класса:
Извините, вам запрещён просмотр содержимого спойлеров.

Как временное и плохое  решение, эту строку можно заменить на
Код - C# [Выбрать]
  1.         m_val = new ArrayList();
  2.         foreach (object i in val)
  3.           m_val.Add(i);
Так автокад хотя бы с фаталом вылетать перестаёт и видно наличие гиперссылок у объекта, однако из-за вот этого вот "копирования" списка получается побочный эффект:если тыкнуть на  список гиперссылок, то появится исключение AccessViolationException в методе Stream(ArrayList data, HyperLink hlink) , это 841 строка класса MgdDbg.Snoop.CollectorExts.DbMisc

Тут код этого метода:
Извините, вам запрещён просмотр содержимого спойлеров.

Хотелось бы совета и направления, как все это поправить...

Оффлайн Александр РивилисАвтор темы

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Увы, но это похоже на баг в самом AutoCAD .NET API. Нормального способа обойти его я не нашёл.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр РивилисАвтор темы

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Владимир Шу,
Хм. Интересный момент. Я заменил код на этот:
Код - C# [Выбрать]
  1.   ObjectCollection(string label, System.Collections.ICollection val)
  2.   : base(label)
  3.     {
  4.       if (val == null)
  5.         m_val = null;
  6.       else
  7.       {
  8.  
  9.         if (val is HyperLinkCollection)
  10.         {
  11.           HyperLinkCollection hs = val as HyperLinkCollection;
  12.           m_val = new ArrayList();
  13.           for (int i = 0; i < hs.Count; i++)
  14.           {
  15.             HyperLink h = new HyperLink();
  16.             h = hs[i];
  17.             h.Name = hs[i].Name;
  18.             h.Description = hs[i].Description;
  19.             h.SubLocation = hs[i].SubLocation;
  20.             m_val.Add(h);
  21.           }
  22.         }
  23.         else
  24.         {
  25.           m_val = new ArrayList(val);
  26.         }
  27.       }
  28.     }

И похоже заработало. Проверял правда в AutoCAD 2020.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
В 2017 не заработало, как и ожидал (Ваш код по сути то же, что сделал и я, т.е. копию списка, а не приведение существующего к нужному типу) получил "System.AccessViolationException: "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." в MgdDbg.Snoop.CollectorExts.DbMisc строка 846

Оффлайн Александр РивилисАвтор темы

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
В 2017 не заработало, как и ожидал (это по сути то же, что сделал и я, т.е. копию списка, а не переопределение того же самого)
Нет. Это не переопределение списка. HyperLinkCollection привязан к примитиву, на который он ссылается. И если примитив закрыт, то HyperLinkCollection становится невалидной. А вот такое переписывание элементов помогает. Но почему-то потребовалось и скопировать сам элемент из HyperLinkCollection и еще и переназначить доступные для изменения свойства.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
я понимаю, что Вы, как и я, пошли по пути создания нового списка (выделение нового куска памяти и создание объектов в этом новом куске, вместо сохранения ссылки на существующий кусок памяти), но это (в случае с 2017 акадом) приводит к исключению System.AccessViolationException и я подозреваю, что нужно не создавать копию списка, а как то передать оригинал, предварительно переопределив его тип.


ЗЫ.
Странно, если копнуть несколько глубже, то вот тут: https://referencesource.microsoft.com/#mscorlib/system/collections/arraylist.cs можно посмотреть кишки типа ArrayList и там внутри, в конструкторе принимающим ICollection и далее по методам,  видно, что создается новый массив объектов... Фигня какая я то, штатное создание ArrayList вызывает фатал, а если самому в рукопашную сделать то же самое, то фатала нет, но появляется System.AccessViolationException...  Что то пазл в голове не складывается.

Оффлайн Александр РивилисАвтор темы

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Владимир Шу,
Да. Я перепроверил и в 2017 это не работает. Но зато работает такой:
Код - C# [Выбрать]
  1.   ObjectCollection(string label, System.Collections.ICollection val)
  2.   : base(label)
  3.     {
  4.       if (val == null)
  5.         m_val = null;
  6.       else
  7.       {
  8.  
  9.         if (val is HyperLinkCollection)
  10.         {
  11.           HyperLinkCollection hs = val as HyperLinkCollection;
  12.           m_val = new ArrayList();
  13.           for (int i = 0; i < hs.Count; i++)
  14.           {
  15.             HyperLink h = new HyperLink();
  16.             h.Name = hs[i].Name;
  17.             h.Description = hs[i].Description;
  18.             h.SubLocation = hs[i].SubLocation;
  19.             m_val.Add(h);
  20.           }
  21.         }
  22.         else
  23.         {
  24.           m_val = new ArrayList(val);
  25.         }
  26.       }
  27.     }
  28.  

(т.е. нет h = hs[i])

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр РивилисАвтор темы

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Что то пазл в голове не складывается.
Это же обертка над native кодом. Видимо не слишком корректная.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
Спасибо. Все заработало. Выглядит как некоторый костыль, но работает.
Надо как то это в репозиторий закинуть, у меня не получилось =( или пора форумный форк делать =)

Оффлайн Александр РивилисАвтор темы

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Спасибо. Все заработало. Выглядит как некоторый костыль, но работает.
Надо как то это в репозиторий закинуть, у меня не получилось =( или пора форумный форк делать =)
Если честно, то я не слишком продвинутый GIT-пользователь. Так что с форком не подскажу, а вот исправленные исходники и бинарники уже в архиве, указанном в первом сообщении темы.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Надо как то это в репозиторий закинуть, у меня не получилось
Надо сначала сделать Fork, потом внести изменения, а потом сделать Pull Request и ждать, пока автор оригинального репозитория примет этот ПР

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
и ждать, пока автор оригинального репозитория примет этот ПР
Боюсь, никогда. Проектом не занимаются.

Оффлайн Александр РивилисАвтор темы

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Обратил внимание, что режиме Browse Using Reflection... можно не только просматривать, но и редактировать свойства объекта.



Была единственная загвоздка в том, что объект открывался "для чтения" и при попытке модификации AutoCAD валился с сообщением об ошибке. Я это исправил:


Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 546
  • Карма: 119
можно не только просматривать, но и редактировать свойства объекта.
Жаль, что у меня старая версия. Полезная функция.
А свойства для чтения, ну например Polyline.NumberOfVertices, Polyline.Length программа определяет и не дает редактировать?

Оффлайн Александр РивилисАвтор темы

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Жаль, что у меня старая версия. Полезная функция.
Я перекомпилировал для версий начиная с 2012. Для более ранних наверное работать не будет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение