Обходной путь "Динамическое преобразование интерфейса не поддерживается конфигурацией"
У меня есть объектно-ориентированный дизайн следующим образом (Ада 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
- GPRBILD Pro 18+
Что я пробовал до сих пор:
- Измените реализацию фабрики с явным приведением или явным распределением временных переменных:
Образец:
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 ответ
Сообщение "не поддерживается конфигурацией" намекает на то, что это ограничение времени выполнения. И вы используете среду выполнения ZFP, которая имеет серьезные ограничения, когда речь идет, например, о неопределенных типах (таких как общеклассовые типы и неограниченные массивы).
Документация времени выполнения должна предоставить больше информации об этих ограничениях.