Как предотвратить компоновщик от оптимизации кода запуска? - PullRequest
3 голосов
/ 19 августа 2009

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

// Foo.cpp

static TFooRegistry sFooRegistry;   // does stuff in constructor.

При сборке моего проекта с использованием dll для каждого подпроекта все работает нормально, и код выполняется должным образом. Однако при статическом связывании подпроектов компоновщик определяет, что Foo.o не содержит кода, на который когда-либо ссылались извне, и оптимизирует его. Конечно, я мог бы добавить ссылку на sFooRegistry где-нибудь еще, но это утомительно и подвержено ошибкам.

Какие (стандартные совместимые) способы решения этой проблемы существуют?

ОК, что я могу сделать на Mac / GCC и Win / Visual Studio?

Ответы [ 2 ]

4 голосов
/ 19 августа 2009

Стандартных и согласованных способов принудительного инициализации объектов в библиотеках не существует - необходимо использовать приемы в зависимости от конкретной платформы (платформ). Разница между DLL и статической библиотекой (по крайней мере в Windows) заключается в том, что первый имеет код запуска и завершения работы, который выполняется ОС, тогда как последний представляет собой просто конкатенацию объектных файлов.

Кроме того, компоновщик не оптимизирует ваш стартовый код - он просто не связывает его, потому что он, очевидно, никогда не используется. Linkers довольно глупые звери - если вы хотите узнать, как они делают то, что делают, посмотрите в книге Линкеры и загрузчики .

1 голос
/ 19 августа 2009

Какой-то трюк, но просмотрите его. Для системы Win (но не для Linux) используйте явный dllexport - в этом случае компоновщик не знает, используется этот символ внешним приложением или нет.

...