библиотеки по умолчанию, а специальный атрибут, аналогичный __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.