библиотеки по умолчанию, а специальный атрибут, аналогичный __declspec(dllexport) в Windows, используется в исходном коде для изменения видимости символов по отдельности. Опция -fvisibility имеет несколько различных значений, но два наиболее интересных — это
extern __attribute__((visibility('default'))) int m; // экспортируется
extern int n; // не экспортируется
__attribute__((visibility('default'))) void f(); // экспортируется
void g(); // не экспортируется
struct __attribute__((visibility('default'))) S { }; // экспортируется
struct T { }; //не экспортируется
В примере 1.7 атрибут __attribute__((visibility('default'))) играет ту же роль, что и __declspec(dllexport) в коде Windows.
Использование атрибута visibility представляет те же проблемы, что и использование __declspec(dllexport) и __declspec(dllimport), так как вам требуется, чтобы этот атрибут присутствовал при сборке общей библиотеки и отсутствовал при компиляции кода, использующего эту общую библиотеку, и чтобы он полностью отсутствовал на платформах, его не поддерживающих. Как и в случае с __declspec(dllexport) и __declspec(dllimport) , эта проблема решается с помощью препроцессора. Например, вы можете изменить заголовочный файл
#ifndef GEORGERINGO_HPP_INCLUDED
#define GEORGERINGO_HPP_INCLUDED
// определите GEORGERINGO_DLL при сборке libgeorgeringo
#if defined(_WIN32) && !defined(__GNUC__)
#ifdef GEORGERINGO_DLL
#define GEORGERINGO_DECL __declspec(dllexport)
#else
#define GEORGERINGO_DECL __declspec(dllimport)
#endif
#else // Unix
# if defined(GEORGERINGO_DLL) && defined(HAS_GCC_VISIBILITY)
# define GEORGERINGO_DECL __attribute__((visibility('default')))
# else
#define GEORGERINGO_DECL
#endif
# endif
// Печатает 'George, and Ringo
'
GEORGERINGO_DECL void georgeringo();
#endif // GEORGERINGO_HPP_INCLUDED
Чтобы заставить это работать, вы должны при сборке в системах, поддерживающих опцию HAS_GCC_VISIBILITY.
Последние версии компилятора Intel для Linux также поддерживают опцию
Metrowerks для Mac OS X предоставляет несколько опций для экспорта символов из динамической библиотеки. При использовании IDE CodeWarrior вы можете использовать файл #pragma export, и указание в командной строке #pragma export иллюстрируется в примере 1.2: просто вызовите #pragma export on в ваших заголовочных файлах сразу перед группой функций, которые требуется экспортировать, а сразу после нее — #pragma export off. Если вы хотите, чтобы ваш код работал с инструментарием, отличным от Metrowerks, вы должны поместить обращения к #pragma export между директивами #ifdef/#endif, как показано в примере 1.2.
Давайте кратко посмотрим на опции, использованные в табл. 1.11. Каждая строка команды определяет:
• имя (имена) входного файла (файлов):
• имя создаваемой динамической библиотеки;
• в Windows имя библиотеки импорта.
Кроме того, компоновщик требует опции, которая говорит ему создать динамическую библиотеку, а не исполняемый файл. Большинство компоновщиков используют опцию
Несколько опций в табл. 1.11 способствуют более эффективному использованию динамических библиотек во время выполнения. Например, некоторым компоновщикам для Unix требуется с помощью опции
Передать опцию в компоновщик GCC можно через компилятор, используя опцию
Большая часть других опций используется для указания вариантов рабочей библиотеки и описывается в рецепте 1.23.
