2013-05-08 2 views
0

У меня есть следующая проблема для решения.Решение о построенных объектах во время компиляции

У меня есть компонент А. Этот компонент имеет некоторые подкомпоненты - B, C, D. Используя cmake, я создаю или не те компоненты B, C, D. Это зависит от конфигурации текущей платформы. Моя система cmake делает исполняемые make-файлы (для компонента A) для связывания только тех компонентов, которые использовались в данном запуске cmake. Если компонент B был построен, он добавляется в исполняемый файл, если нет - не связан. То же самое с другим - C, D.

Все эти компоненты B, C, D предоставляют некоторые реализации интерфейса, используемые в компоненте A. Этот компонент должен управлять объектами, созданными B, C, D, и сохранять эти объекты на некоторой карте, используя надлежащий объект в надлежащее время.

Вопрос:

Я хочу, чтобы достичь какого-то простого и надежного механизма для добавления этих объектов, реализующим интерфейс автоматически, так же, как сейчас с привязкой - связанно только модули, которые были построены. То же самое с этими объектами - я хотел бы, чтобы они были зарегистрированы в компоненте A только тогда, когда они были скомпилированы.

Мне трудно объяснить это. Идея проста - построить некоторую карту этих объектов во время компиляции. Компилируемые компоненты должны доставить свой объект на эту карту.

+1

Вы можете решить эту проблему, используя директивы препроцессора, установленные системой makefile/cmake. Например, если компонент B скомпилирован и должен быть включен при компиляции A, вы можете использовать директивы, такие как '#ifdef COMPILED_B', чтобы включить поддержку B в A, когда это необходимо. –

+0

Да, это возможно, но я бы хотел избежать #ifdef в исходном коде. Я просто хотел узнать, как другие люди делают это более сложным способом. – user2301299

ответ

1

Я использовал конструкции, похожие на методы реализации Objective-C и Smalltalk.

В C++ методы == функции-члены и должны быть определены во время компиляции. Таким образом, хотя интерфейс может быть расширен с помощью таких механизмов, как препроцессор, такая же конфигурация также должна влиять на любых клиентов класса или просто не будет связываться.

Поэтому я использую систему передачи сообщений для вызова методов объектов. Поэтому, если A является основным классом и вы компилируете в C и D, но не B, тогда процессор сообщений A будет отвечать только на сообщения, которые имеют обработчики, зарегистрированные C и D.

Этот тип дизайна требует наличия система обмена сообщениями. Существует множество существующих систем, таких как буферы протокола Google и Apache Thrift. Я выбрал дизайн, так как я хотел еще больше конфигурации, чем большинство существующих систем (многие из этих систем обмена сообщениями используют IDL-компиляторы).

Однако это позволило мне приблизиться к сфере ОО, чем обычно допускает язык смешанной парадигмы, который обычно разрешает C++.

+0

Итак, в вашем случае компоненты, которые были скомпилированы (C, D), должны были иметь объекты глобальной области (инициализированные при запуске процесса), которые регистрировались в качестве обработчиков для какого-либо глобального диспетчера сообщений? Они делали это от своих конструкторов? – user2301299

+1

Конструктор A ищет путь для общих объектов. Если они существуют, он загружает их и вызывает функцию инициализации (стандартное имя для всех компонентов). Инициализатор вводит свои возможности в систему обмена сообщениями, регистрируя имена методов и связанные адреса. Параметры передаются как пары ключ-значение как часть сообщения. API запросов нового компонента можно запросить для получения списка команд, параметров, единиц, пределов/диапазонов и некоторого описания.Это немного на сложной стороне, но нацелено на легкое обслуживание большой распределенной системы. –

+0

В одном конкретном примере конструктору передается строка, представляющая путь к каталогу компонентов для этого проекта. Затем API OS используется для поиска и загрузки общего объекта (DLL для сборки Windows) и динамической привязки в коде. Объекты включают в себя их функциональность, реализованную как обработчики сообщений, а также функцию init, которая может внедрять их функциональность в систему обмена сообщениями. Указатель на клиент сообщения передается функции init, чтобы он мог выполнять регистрационные вызовы. –

Смежные вопросы