Официальный форум российского программного комплекса 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