Официальный форум российского программного комплекса T-FLEX PLM


Поиск  Правила 
Закрыть
Логин:
Пароль:
Забыли свой пароль?
Регистрация
Войти
 
Страницы: 1
Проблема с работой TFlex API
 
Здравствуйте, уважаемые старожилы и гости форума.
Пишу макрос для TFlex CAD 10.0.57.0, который показывает информацию о выделенном объекте документа. В частности, для линий типа Outline пишу код:

Код
ModelObject mo = doc.Selection.GetAt(0) as ModelObject;   //Исследуем первый выделенный объект
 ...
switch (mo.GroupType)   //Перебираем тип объекта
...
case ObjectType.Outline:   //Найдена линия изображения
   Outline ol = mo as Outline;
   if (ol == null)
   {
      MessageBox.Show("Объект определён как \"" + mo.GroupType.ToString() + "\", но при преобразовании к типу \"" +
         "\"Outline\" объект получил значение null.");
      try
      {
         ol = (ProjectionOutline)mo;
      }
      catch (Exception e)
      {
         ReportForm errForm = new ReportForm();
         errForm.SetReportText(e.Message);
         errForm.ShowDialog();
      }
В документе я выбираю линию изображения, полученную с проекции (класс ProjectionOutline). Согласно документации на TFlex API имеем:

Код
__gc class ProjectionOutline : public Model2D::Outline;
Значит, я могу обращаться к ProjectionOutline через переменную базового класса Outline.
При выполнении строки
Код
ol = (ProjectionOutline)mo;
генерируется исключение вот с таким сообщением (содержится в e.Message):
[A]TFlex.Model.Model3D.ProjectionOutline невозможно привести к [B]TFlex.Model.Model3D.ProjectionOutline.
Тип A происходит от ТFlехАРI3D, Version=9.0.0.0, Culture=neutral, PublicKeyToken=28c4a25ab632a509 в контексте "LoadFrom" в расположении "C:\PROGRA~1\T-FLEX\T-FLEX~3\Program\ТFlехАРI3D.dll.
Тип B происходит от ТFlехАРI3D, Version=9.0.0.0, Culture=neutral, PublicKeyToken=28c4a25ab632a509" в контексте "Default" в расположении "C:\Program Files\T-FLEX\T-FLEX CAD 10\Program\ТFlехАРI3D.dll.
Подскажите пожалуйста, что может быть не так? При компиляции проекта в свойствах ссылок на ТFlехАРI.dll и ТFlехАРI3D.dll свойство "CopyLocal == false".
Буду благодарен за любые мысли по поводу причин происхождения вышеописанного сообщения. Просто не могу понять, куда дальше копать.
Изменено: Николай - 01.12.2013 00:09:11
 
Цитата
Николай пишет:
Просто не могу понять, куда дальше копать.

При обращении к ProjectionOutline через переменную базового класса правильная работа не гарантирована. Специалисты говорят, что в этом случае надо использовать Dynamic Cast.

Вообще, было бы интересно узнать зачем вообще вам потребовалось ))
 
Здравствуйте, уважаемый Osiris2000.
Спасибо за внимание к моей проблеме.
Цитата
При обращении к ProjectionOutline через переменную базового класса правильная работа не гарантирована.
Если возможно, поясните, почему нельзя обращаться к экземпляру класса TFlex.Model.Model3D.ProjectionOutline через переменную базового класса TFlex.Model.Model2D.Outline?
И как мне можно было бы действовать наиболее корректно для решения следующей задачи:
Мой макрос должен выводить информацию из свойств выбранного объекта. Для этого я получаю сперва 1й выбранный объект, остальные не рассматриваю:

Код
ModelObject mo = doc.Selection.GetAt(0) as ModelObject;   //Исследуем первый выделенный объект
Затем проверяю, что же хранится в mo:
Код
switch (mo.GroupType)   //Перебираем тип объекта
...
   case ObjectType.Outline:   //Найдена линия изображения
   Outline ol = mo as Outline;
В данном случае я хочу только лишь считать свойства объекта типа Outline. Но если я выбираю линию на проекции и запускаю макрос, то mo будет содержать ссылку на экземпляр класса ProjectionOutline.
Что может плохого произойти, когда выполнится строка:
Код
Outline ol = mo as Outline;
Понятно, что при любых накладках ol будет null. Но мне нужен "действительный" результат, для считывания данных или любых других операций.
 
Прошу прощения за оформление ответа в виде нескольких сообщений, но из-за длинных постов система меня банит.
Цитата
Вообще, было бы интересно узнать зачем вообще вам потребовалось ))
Код
ol = (ProjectionOutline)mo;
и всю обвязку с исключениями я написал для того, чтобы понять, почему при выборе линии с проекции я не могу считать с неё информацию. Потому что строка
Код
Outline ol = mo as Outline;
постоянно давала null. То есть только ради того, чтобы явным преобразованием выявить возникающее исключение и максимально подробно выяснить, что происходит.
Хотя на самом деле то конечно дело не в макросе для получения информации, это я просто для примера привожу. У меня написано несколько макросов, работающих с линиями, работа идёт через переменные класса Outline. И всё работает, пока не начинаю выбирать для обработки линии с проекций. Поэтому очень хочу досконально разобраться, почему именно линии с проекций (класс ProjectionOutline) так странно себя ведёт при доступе через переменную Outline. Чувствую, что собака зарыта тут:

Код
class ProjectionOutline : public Model2D::Outline;   //из документации на API
Ведь ProjectionOutline определён в сборке ТFlехАРI3D.dll, a Outline - в TFlexAPI.dll. И какой-то ньюанс на этом стыке видимо и возникает. Но какой?
Изменено: Николай - 04.12.2013 21:16:50
 
Николай, попробуйте сделать так:


ProjectionOutline Pln = mo as ProjectionOutline;
if (Pln != null)
{
//Сделать необходимые действия
}

//Иначе продолжить работу с обычными линиями
 
Уважаемый Osiris2000, при выполнении строки

Код
ProjectionOutline Pln = mo as ProjectionOutline; 
Pln всегда получает значение null при выборе линии на проекции.
Если я пишу вот так:

Код
Pln = (ProjectionOutline)mo;
то возникает то же самое исключение System.InvalidCastException с тем же самым сообщением про невозможность привести тип А к типу В.
Есть странность: сборки ТFleхАРI.dll и ТFleхАРI3D.dll загружены 2 раза (перебираю AppDomain.CurrentDomain.GetAssemblies() ):
Загруженные сборки:
 
FullName: mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
CodeBase: file:///C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll
FullName: TFlexMacroLoader, Version=9.0.0.0, Culture=neutral, PublicKeyToken=aad0660c964b52ef
CodeBase: file:///C:/Program Files/T-FLEX/T-FLEX CAD 10/Program/TFlexMacroLoader.DLL
FullName: msvcm80, Version=8.0.50727.4027, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
CodeBase: file:///C:/WINDOWS/WinSxS/x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.4027_x-ww_e69378d0/msvcm80.dll
FullName: TFlexAPI, Version=9.0.0.0, Culture=neutral, PublicKeyToken=eab6a180a6be0d77
CodeBase: file:///C:/PROGRA~1/T-FLEX/T-FLEX~3/Program/TFlexАРI.dll
FullName: ТFleхАРI3D, Version=9.0.0.0, Culture=neutral, PublicKeyToken=28c4a25ab632a509
CodeBase: file:///C:/PROGRA~1/Т-FLEХ/Т-FLEХ~3/Program/ТFleхАРI3D.dll
Изменено: Николай - 05.12.2013 20:17:00
 
FullName: shqbg0gftfm, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
CodeBase: file:///C:/Program Files/T-FLEX/T-FLEX CAD 10/Program/TFlexMacroLoader.dll
FullName: cnvndeootfm, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
CodeBase: file:///C:/Program Files/T-FLEX/T-FLEX CAD 10/Program/TFlexMacroLoader.dll
FullName: MacroLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
CodeBase: file:///C:/Program Files/T-FLEX/T-FLEX CAD 10/Program/MacroLibrary.DLL
FullName: ТFleхАРI, Version=9.0.0.0, Culture=neutral, PublicKeyToken=eab6a180a6be0d77
CodeBase: file:///C:/Program Files/T-FLEX/T-FLEX CAD 10/Program/ТFlexАРI.DLL
FullName: System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
FullName: System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
FullName: ТFleхАРI3D, Version=9.0.0.0, Culture=neutral, PublicKeyToken=28c4a25ab632a509
CodeBase: file:///C:/Program Files/T-FLEX/T-FLEX CAD 10/Program/ТFlexАРI3D.DLL
Таким образом, почему-то ТFlexАРI.dll, ТFlexАРI3D.dll загружен 2 раза. И почему-то они отличаются формой записи пути в CodeBase (формат ДОС 8.3 и формат длинного имени).
Также несколько раз встречается ТFleхMacroLoader.dll. По каким причинам ТFlexАРI.dll, ТFlexАРI3D.dll могут загружаться 2 раза?
Изменено: Николай - 05.12.2013 20:20:33
 
Частично решил свою проблему, установив ТFleхАРI.dll и ТFleхАРI3D.dll в глобальный кеш сборок.
Исключение System.InvalidCastException не выбрасывается, ТFleхАРI.dll и ТFleхАРI3D.dll перестали загружаться 2 раза.
Макрос заработал, но я заметил странности:
1. при выборе линии на проекции её тип стал определяться как TFlex.Model.Model2D.Outline;
2. свойство Outline.SybType == Undefined.
То есть если мне понадобится доступ к свойствам класса ProjectionOutline - ничего не выйдет.
В чём глобальная причина выяснить так и не удалось, подозреваю, что на моей машине какие-то проблемы с NET Framework.
При запуске макроса на другой машине с Windows 7 макрос отрабатывает абсолютно корректно, без установки ТFleхАРI.dll и ТFleхАРI3D.dll в GAC.
Изменено: Николай - 09.12.2013 19:47:34
Страницы: 1