Сохранение переменных глобально для области видимости библиотеки в C - PullRequest
2 голосов
/ 16 апреля 2009

Есть ли способ сохранить глобальные переменные видимыми только изнутри библиотеки, в то время как они недоступны для программ, которые обращаются к этой библиотеке в C?

Дело не в том, что важно хранить переменную защищенной, но я бы предпочел, чтобы программы не могли импортировать ее, поскольку это не их дело.

Меня не волнуют решения, включающие макросы.

Ответы [ 4 ]

9 голосов
/ 16 апреля 2009

Если вы используете g ++, вы можете использовать средства компоновки для этого, используя атрибуты.

__attribute__((visibility("hidden"))) int whatever;

Вы также можете пометить все как скрытое и явно отметить то, что видно с помощью этого флага:

А затем пометьте видимые переменные с помощью:

__attribute__((visibility("default"))) int whatever;
7 голосов
/ 16 апреля 2009
static int somelocalvar = 0;

, который делает somelocalvar видимым только из исходного файла, где он объявлен ( ссылка и пример ).

6 голосов
/ 16 апреля 2009

Внутри реализации библиотеки объявите переменные следующим образом:

struct my_lib_variables
{
  int var1;
  char var2;
};

Теперь в заголовке для конечных пользователей, объявите это так:

struct my_lib_variables;

Он объявляет структуру как неполный тип . Люди, которые будут использовать заголовок, смогут создать указатель на структуру, но это все. Цель состоит в том, чтобы они написали что-то вроде этого:

#include "my_lib.h"

struct my_lib_variables* p = my_lib_init();
my_lib_do_something(p);
my_lib_destroy(p);

Код libray может изменять переменные, но библиотека не может сделать это напрямую.


Или вы можете использовать глобальные переменные, но поместите объявления extern в заголовок, который не будет использоваться конечным пользователем.

0 голосов
/ 16 апреля 2009

Вы можете использовать другой файл заголовка для экспорта функциональности во внешние модули, чем для внутренней функциональности, поэтому вам не нужно объявлять глобальные переменные, которые не должны быть доступны извне модуля.

Edit: Есть проблемы с компоновщиком, если вы объявляете вещи более одного раза. Нет необходимости хранить все глобальные данные в одном заголовочном файле, на самом деле, может быть разумная причина разделить их на несколько более мелких частей для удобства обслуживания и различных областей ответственности. Разделение на заголовочные файлы для внешних данных и внутренних данных является одной из таких причин, и это не должно быть проблемой, поскольку возможно включить более одного заголовочного файла в один и тот же исходный файл. И не забывайте охрану в заголовочных файлах, таким образом, столкновение при связывании в основном избегается.

#ifndef XXX_HEADER_FILE
#define XXX_HEADER_FILE
code
#endif
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...