Обходной путь «Динамическое преобразование интерфейса не поддерживается конфигурацией» - PullRequest
0 голосов
/ 12 июня 2018

У меня есть объектно-ориентированный дизайн следующим образом (Ада 2012).Вопрос не в самом дизайне, а в его последствиях для конкретного профиля времени выполнения.

-- several packages ommitted here, ads/adb mixed together
type Interface_A is interface;
type Interface_A_Class_Access is access all Interface_A'Class;

type Interface_B is interface and Interface_A;
type Interface_B_Class_Access is access all Interface_B'Class;

type Interface_C is interface and Interface_B
type Interface_C_Class_Access is access all Interface_C'Class;

type B_Impl is abstract tagged ...;
type B_Impl_Access is access all B_Impl;
type C_Impl is new B_Impl and Interface_C ...;
type C_Impl_Access is access all C_Impl;

function Create_C return C_Impl_Access is begin
   return new C_Impl'(...);
end Create;

У меня есть фабрика для создания экземпляров объектов Interface_A, Interface_B или Interface_C.

package body My_Factory is
   procedure Create_A return Interface_A_Class_Access is begin
      return Create_A_Impl; -- error: dynamic interface conversion not supported by configuration
   end Create_B;

   procedure Create_B return Interface_B_Class_Access is begin
      return Create_C_Impl; -- error: dynamic interface conversion not supported by configuration
   end Create_B;

   procedure Create_C return Interface_C_Class_Access is begin
      return Create_C_Impl; -- error: dynamic interface conversion not supported by configuration
   end Create_C;
end package My_Factory;

С обоими коммутаторами я получаю следующую ошибку для обеих функций создания фабрики:

error: dynamic interface conversion not supported by configuration

Среда:

  • GNAT 17.2
  • ZFP MPC8641
  • GPRBUILD Pro 18 +

То, что я пробовал до сих пор:

  1. Изменение реализации фабрики с явным приведением или явным выделением временной переменной:

Образец:

package body My_Factory is
   ...
   procedure Create_B return Interface_B_Class_Access is begin
      return Interface_B_Class_Access(Create_C); -- error: dynamic interface conversion not supported by configuration
   end Create_B;

   procedure Create_C return Interface_C_Class_Access is
      tmp : Interface_C_Class_Access;
   begin
      tmp := Create_C; -- error: dynamic interface conversion not supported by configuration
      return tmp;
   end Create_C;
end package My_Factory;

Та же проблема.

Добавить явные методы конструктора (влияние на 'new' в переменной доступа к классу)

Пример:

function Create_C return Interface_A_Class_Access is begin
   return new C_Impl'(...); -- error: dynamic interface conversion not supported by configuration
end Create;

function Create_C return Interface_B_Class_Access is
   tmp : Interface_B_Class_Access;
begin
   tmp := new C_Impl'(...); -- works fine
   return tmp;
end Create;

function Create_C return Interface_C_Class_Access is
   tmp : Interface_B_Class_Access;
begin
   tmp := new C_Impl'(...); -- works fine
   return tmp;
end Create;

Этот второй вариант работает нормально.

При стандартном профиле проблем не возникает.Я столкнулся с проблемой во время (наивно) портирования в определенный профиль.Насколько я понимаю, это законный объектно-ориентированный дизайн, но некоторые конструкции не обрабатываются одинаково.

Мои вопросы:

  1. Мой второй вариант приемлем?Почему это работает?

  2. Я что-то упустил?Я понимаю, что это в какой-то степени связано с управлением таблицами диспетчеризации с помощью кода, сгенерированного компилятором, но я не совсем понимаю, что такое механика / причины.

1 Ответ

0 голосов
/ 12 июня 2018

Сообщение «не поддерживается конфигурацией» намекает на то, что это ограничение времени выполнения.И вы используете среду выполнения ZFP, которая имеет серьезные ограничения, когда речь идет, например, о неопределенных типах (таких как общеклассовые типы и неограниченные массивы).

Документация времени выполнения должна предоставлять большеинформация об этих ограничениях / ограничениях.

...