2013-12-16 2 views
3

Прошу прощения, если название этого сообщения не совсем подходит для последующего использования.Замена для линкеров в чистом виде C

В моем текущем проекте, у меня есть разные .c файлы (то есть. *controller_1.c*, controller_2.c и main.c). Каждый файл «controller» использует макрос для определения структуры «контроллера». Эта структура закончится в определенном разделе внутри моего окончательного исполняемого файла. Вот макрос:

#define CONTROLLER_START(_name)      \ 
    static struct controller controller_##_name  \ 
    __attribute__((         \ 
    __used__,           \ 
    __section__("controllers"),      \ 
    __aligned__(__alignof__(struct controller)))) = { \ 
    .name = #_name, 
    #define CONTROLLER_END,       \ 
}; 

Это хороший трюк (используется в ядре Linux) позволяет мне скомпилировать мой проект и «открыть» различные контроллеры во время выполнения. Я просто должен указать на начало этого раздела контроллера и пройти через все из них. Проблема, с которой я сталкиваюсь, заключается в том, что, хотя это работает под Linux, Windows и OSX, этот метод трудно или невозможно реализовать на других операционных системах (или через Emscripten, который я пробовал).

Я хотел бы повторно реализовать эту часть без использования сценариев компоновщика. Цель состоит в том, чтобы избежать необходимости использовать extern в файле .c, где я разбираю эти структуры и, конечно же, избегаю включения (у меня могут быть сотни таких файлов контроллера). Я не уверен, возможно ли это, но некоторые люди в переполнении стека могут знать о подобном трюке, который более переносим.

Спасибо!

+1

Если вы можете использовать C++, вы можете использовать конструкторы для регистрации ваших контроллеров во время запуска. Вы также можете сделать это в C, если вы используете атрибут функции «конструктор» в GCC – dsi

+1

@dsi: хотя это может сработать, это действительно уродливое «решение». Он заменяет то, что является фундаментально постоянными таблицами с глобальным состоянием. И, конечно, есть всевозможные неприятные проблемы, такие как тот факт, что другие ctors могут работать до того, как запущены некоторые или все регистрационные центры. –

+1

@R .. вы можете использовать конструкторы для регистрации (вставки) контроллера в связанный список (т. Е. Иметь глобальный указатель на первый). Приказ не имеет большого значения. Фактическая обработка будет выполняться позже в main(), например, и до этого эти контроллеры вообще не должны использоваться. Я вижу вашу точку зрения. – dsi

ответ

1

Простой ответ: вы не можете. Вот почему ядро ​​linux и другие проекты используют этот раздел. Вы можете использовать расширения компилятора, такие как конструкторы. Или вы можете исправить трюк раздела для работы в большинстве операционных систем. Но нет никакого способа сделать это в чистом C.

У меня есть hack on github для настройки разделов, которые раньше работали с MacOS и большинством unix-подобных систем с ELF и a.out. Но это лучшее, что вы можете сделать.

+0

Спасибо всем. У меня уже есть работа под OSX, Linux и Windows. Меня интересуют Emscripten и мобильные ОС (в основном, Android и iOS). Будет ли атрибут конструктора работать для таких целей? – user1995488

+1

@ user1995488 он должен работать (он определенно будет работать с конструкторами C++, возможно, C тоже). Очевидно, что другой вариант - написать инструмент (например, скрипт), который перечислил бы все ваши контроллеры в файл C, содержащий массив указателей, которые вы затем получили бы как есть из вашей основной программы. – dsi

+0

Я тоже думал о скрипте или даже исправлял источник, но он явно слишком взломан для моего вкуса. Спасибо за отзыв всем! – user1995488

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