Скомпилированы ли определения препроцессора в библиотеку? - PullRequest
4 голосов
/ 24 августа 2010

Они (определения препроцессора) скомпилированы в статическую / динамическую библиотеку?Например, FBX SDK требуется KFBX_DLLINFO.Библиотека, которая использует FBX SDK , должна включать это.Теперь, насколько я могу судить по моему ограниченному эксперименту, клиентское приложение не должно объявлять определение снова.

Теперь я не могу придумать более практичный сценарий, но что если клиентскому приложению «нужно» исключить определение (например, _CRT_SECURE_NO_WARNINGS, скомпилированное с библиотекой, но что если мне понадобятся эти предупреждения?

Ответы [ 3 ]

16 голосов
/ 24 августа 2010

Короче говоря: нет.

В длинных: По большей части вы можете думать об определениях препроцессора как о текстовом механизме замещения. Они обрабатываются до того, как происходит компиляция ( pre -компиляция), поэтому они преобразуют исходный код непосредственно перед тем, как компилятор преобразует его в машинный код, промежуточные файлы или что-либо еще, для чего он предназначен. К тому времени, когда у вас есть бинарный файл lib / obj / dll / exe / so, определения препроцессора уже давно отсутствуют.

Если вы включаете в свой код заголовок, который был упакован как часть библиотеки (например, для ссылки на методы, типы, перечисления и т. Д., Определенные библиотекой), то вы включаете определения препроцессора, которые определяет библиотека в этот заголовок.

В вашем случае, если вы включите заголовок FBX, вы также можете использовать определение препроцессора KFBX_DLLINFO. Бинарная библиотека FBX, с которой вы ссылаетесь, почти наверняка была создана с тем же заголовком, так что вы строите с тем же определением. Это общий шаблон для библиотек, написанных на C / C ++: общие, совместно используемые заголовочные файлы вместе со статической или динамической библиотекой для сборки.

2 голосов
/ 24 августа 2010

Как объясняет Крис, #defines - это текстовый механизм замещения. Расширение традиционно выполнялось как этап предварительной компиляции, при этом основной компилятор языка C ++ не имел (или не хотел) доступа к тексту перед заменой. По этой причине #defines может делать то, что невозможно с языковыми ограничениями C ++, например, объединять значения для формирования новых идентификаторов. В наши дни компиляторы, как правило, встраивают функциональность обработки макросов и могут включать некоторую информацию о символах препроцессора в таблицы символов отладки, скомпилированные в исполняемые файлы. Не очень желательно или практически невозможно получить доступ к этой отладочной информации для некоторых клиентов, так как форматы отладки и содержимое могут меняться в зависимости от версии компилятора, не очень переносимы, могут быть плохо отлажены: - /, и доступ к ним может быть медленным и неуклюжий.

Если я правильно вас понимаю, вам будет интересно, будет ли #defines из какой-либо библиотеки более низкого уровня, которую использует ваша библиотека, автоматически быть доступным программисту "приложения", использующему вашу библиотеку. Нет, они не будут. Вам нужно либо предоставить свои собственные определения для тех значений, которые API вашей библиотеки предоставляет прикладному программисту (внутреннее сопоставление со значениями библиотеки более низкого уровня, если они различаются), либо также отправить заголовок библиотеки более низкого уровня.

Для примера переназначения:

Ваша библиотека.h:

#ifndef INCLUDED_MY_LIBRARY_H
#define INCLUDED_MY_LIBRARY_H

enum Time_Out
{
    Sensible,
    None
};

void do_stuff(Time_Out time_out);

#endif

Ваша библиотека.c:

#include "my_library.h"
#include "lower_level_library.h"

void do_stuff(Time_Out time_out)
{
    Lower_Level_Lib::do_stuff(time_out == Sensible ? Lower_Level_Lib::Short_Timeout,
                                                   : Lower_Level_Lib::No_Timeout);
    LOWER_LEVEL_LIB_MACRO("whatever");
}

Как показано, использование Lower_Level_Lib не было раскрыто в my_library.h, поэтому программисту приложения не нужно знать или включать в него lower_level_library.h. Если вы обнаружите, что вам нужно / вы хотите поместить файл lower_level_library.h в my_library.h, чтобы использовать в нем его типы, константы, переменные или функции, то вам также потребуется предоставить программисту приложения этот заголовок библиотеки.

2 голосов
/ 24 августа 2010

Определения препроцессора существуют только во время компиляции.Они больше не существуют в скомпилированном двоичном файле, будь то статическая или динамическая библиотека или исполняемый файл.

...