Как создать SAFEARRAY для создания AddRegion

Автор Тема: Как создать SAFEARRAY для создания AddRegion  (Прочитано 20192 раз)

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

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как создать SAFEARRAY для создания AddRegion
« Ответ #60 : 06-02-2020, 21:13:28 »
Александр, здесь я не силён,  если это возможно - добавьте чтобы было = VT_ARRAY|VT_DISPATCH|VT_BYREF

вот тут http://rsdn.org/forum/com/591449.all есть рабочее решение и говорят что без VT_BYREF будет ошибка
Это работает в C++, но не работает в .NET
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Как создать SAFEARRAY для создания AddRegion
« Ответ #61 : 07-02-2020, 01:05:33 »
Это работает в C++, но не работает в .NET
Да. Ситуация не изменилась.
Проверочный код:
Код - C# [Выбрать]
  1. using System;
  2. using System.Runtime.InteropServices;
  3.  
  4. namespace AcadLateCOM
  5. {
  6.     class Program
  7.     {
  8.         [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_DISPATCH | VarEnum.VT_BYREF)]
  9.         static object GetCurves(object curves) => curves;
  10.  
  11.         static void Main(string[] args)
  12.         {            
  13.             dynamic acad = Marshal.GetActiveObject("AutoCAD.Application.23.1");
  14.             dynamic thisDrawing = acad.ActiveDocument;
  15.  
  16.             double[] centerPoint = new[] { 5.0, 3.0, 0.0 };
  17.             double
  18.                 radius = 2.0,
  19.                 startAngle = 0.0,
  20.                 endAngle = Math.PI;
  21.  
  22.             dynamic
  23.                 arc = thisDrawing.ModelSpace.AddArc
  24.                     (centerPoint, radius, startAngle, endAngle),
  25.                 line = thisDrawing.ModelSpace.AddLine
  26.                     (arc.StartPoint, arc.EndPoint);
  27.  
  28.             thisDrawing.ModelSpace.AddRegion(GetCurves(new[] { arc, line }));
  29.         }
  30.     }
  31. }
An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in System.Dynamic.dll
Additional information: Неверный массив объектов

P.S. Интересно, что на работе код работал со строкой "AutoCAD.Application", а дома пришлось добавить "23.1". Иначе отказывался запускаться...

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

  • ADN OPEN
  • Сообщений: 21
  • Карма: 1
  • Skype: maratovich78
Re: Как создать SAFEARRAY для создания AddRegion
« Ответ #62 : 07-02-2020, 07:23:51 »
P.S. Интересно, что на работе код работал со строкой "AutoCAD.Application", а дома пришлось добавить "23.1". Иначе отказывался запускаться...

Это потому что у Вас 2020 Автокад, он сырой до ужаса. Сам не регистрируется в реестре. Нужно перепроверять ветку: HKEY_CLASSES_ROOT\AutoCAD.Application

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Как создать SAFEARRAY для создания AddRegion
« Ответ #63 : 07-02-2020, 12:57:40 »
Попробовал посмотреть что внутри метода AddRegion. Увидел такое объявление:
Код - C# [Выбрать]
  1. // Autodesk.AutoCAD.Interop.Common.IAcadModelSpace
  2. using System.Runtime.CompilerServices;
  3. using System.Runtime.InteropServices;
  4.  
  5. [MethodImpl(MethodImplOptions.InternalCall)]
  6. [DispId(1566)]
  7. [return: MarshalAs(UnmanagedType.Struct)]
  8. new object AddRegion([In] [MarshalAs(UnmanagedType.Struct)] object ObjectList);
  9.  
Я правильно понимаю, что весь наш предварительный маршаллинг коту под хвост, т.к. присутствует маршаллинг параметра на входе в метод?

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как создать SAFEARRAY для создания AddRegion
« Ответ #64 : 07-02-2020, 13:26:22 »
Я правильно понимаю, что весь наш предварительный маршаллинг коту под хвост, т.к. присутствует маршаллинг параметра на входе в метод?
Не думаю. Если бы это было так, то и при раннем связывании код бы не работал.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Как создать SAFEARRAY для создания AddRegion
« Ответ #65 : 07-02-2020, 14:51:56 »
Логично!
Если использовать COM изнутри, то у меня получилось пропихнуть только строго типизированный массив типа AcadEntity[]:
Код - C# [Выбрать]
  1. [CommandMethod("CreateRegionCOMTest")]
  2. public void CreateRegion()
  3. {
  4.     AcadApplication acadApp = Application.AcadApplication as AcadApplication;
  5.     AcadDocument adoc = acadApp.ActiveDocument;
  6.     AcadModelSpace mSpace = adoc.ModelSpace;          
  7.  
  8.     double[] centerPoint = new[] { 5.0, 3.0, 0.0 };
  9.     double
  10.         radius = 2.0,
  11.         startAngle = 0.0,
  12.         endAngle = Math.PI;
  13.  
  14.     AcadArc arc = mSpace.AddArc(centerPoint, radius, startAngle, endAngle);
  15.     AcadLine line = mSpace.AddLine(arc.StartPoint, arc.EndPoint);
  16.  
  17.     AcadEntity[] entities = new AcadEntity[]
  18.     {
  19.         arc as AcadEntity,
  20.         line as AcadEntity
  21.     };            
  22.  
  23.     try
  24.     {
  25.         mSpace.AddRegion(entities);
  26.     }
  27.     catch (System.Exception ex)
  28.     {
  29.         Application.ShowAlertDialog(ex.Message);
  30.     }
  31. }
  32.  
Массивы object[] и dynamic[] тоже вызывали исключения.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
Re: Как создать SAFEARRAY для создания AddRegion
« Ответ #66 : 07-02-2020, 15:23:49 »
А это случайно не раннее связывание?
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как создать SAFEARRAY для создания AddRegion
« Ответ #67 : 07-02-2020, 15:24:42 »
А это случайно не раннее связывание?
Именно. Но об этом Дмитрий Загорулькин и пишет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как создать SAFEARRAY для создания AddRegion
« Ответ #68 : 17-02-2020, 21:30:46 »
maratovich,
Увы, но и сотрудники ADN DevHelp не смогли "победить .NET", хотя испробовали массу вариантов. Создать правильный тип не удалось. Так что остаются только предложенные в данной теме варианты.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 21
  • Карма: 1
  • Skype: maratovich78
Re: Как создать SAFEARRAY для создания AddRegion
« Ответ #69 : 17-02-2020, 22:06:05 »
Увы, но и сотрудники ADN DevHelp не смогли "победить .NET
Спасибо за информацию. Жаль.
Пришлось скрестить .NET  и Lisp кусками, получилась гадость ещё та, но хотя бы так работает.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как создать SAFEARRAY для создания AddRegion
« Ответ #70 : 17-02-2020, 22:14:08 »
Пришлось скрестить .NET  и Lisp кусками, получилась гадость ещё та, но хотя бы так работает.
Именно это и предложили ребята из ADN DevHelp в качестве workaround. Некрасиво, но работает вне зависимости от версии AutoCAD.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение