2016-04-28 2 views
6

Предположим, у меня есть библиотека (A), реализующая шаблон singleton (в его реализации есть статическая переменная).Что происходит со статическими переменными, когда библиотеки статически связаны

(A) библиотека скомпилирована как статическая библиотека.

Теперь, скажем, у меня есть в моем probject:

  • (B), другую статическую библиотеку, связывающую статический (A).
  • (C), другая статическая библиотека, связывающая статически с (A).
  • (D), программа верхнего уровня, связанная с (B) и (C).

В конце концов, мой синглтон действительно одиночный (и моя переменная действительно статична)? Имеются ли (B) и (C), фиксируя ту же статическую переменную от (A) (это unic)? Или тот факт, что (A) был статически связан дважды вложенным кодом (A), дважды заканчивается моей статической переменной от (A), появляющейся дважды в последнем двоичном коде? Тогда, если (B) изменяет значение статической переменной, (C) не увидит изменения?

Примечание: Я испытал это при изменении библиотек проекта, которые будут связаны статически, а не динамически. Мне просто интересно, что я сделал что-то не так, или если это нормальное поведение.

+5

Статическая библиотека в основном представляет собой архив объектных файлов, который привязывается к выходному файлу, как и любой другой объектный файл. –

+0

(D) должен быть связан с (A) также, если для этого требуются символы из (A). (B) и (C) не содержат кода (A). Было бы иначе, если бы (B) и (C) вместо них были dlls/sos. –

+0

Ваши первые два шага не имеют смысла. Статические библиотеки - это сборники модулей объектного кода; они не «связаны» с другими статическими библиотеками. Они просто «там». При построении (D) я не вижу, как только привязка (B) и (C) приведет к окончательной постановке. При вставке в статическую библиотеку, которая требует еще одного статического lib, ответственность за загрузчик (связывание исполняемого файла) заключается в заполнении пробелов (в этом случае также ссылка в (A)), которая должна рассказать вам что-то о сколько (A) находятся в вашей окончательной продукции. – WhozCraig

ответ

6

Прежде всего:

(B) и (C) не связывают с (А). Статические библиотеки скомпилированы, а не связаны. При построении (B) и (C) компилятору, возможно, потребуется увидеть определенные определения из (A), но не путайте это со ссылкой. (A) код не копируется в (B) или (C).

Во-вторых:

(D), придется связать с (А), (В) и (С). Это означает, что вы получаете только одну копию кода (A) в (D).

динамически подключаемая библиотека/общий объект:

Это, конечно, был бы иначе, если (В) и (С) были DLLs/Сос вместо. Dll связаны, и поэтому, если вы создаете (B) и (C) как dll и связываете их с (A), тогда у вас будет отдельная копия кода (A) в обоих (B) и (C).

А (В) и (С) Seing ту же статическую переменную из (A)

Это зависит от того, если переменная имеет external or internal linkage. Следующий заголовочный файл содержит статическую переменную int с взаимной привязкой. Это означает, что каждая единица перевода, которая включает этот файл, получит свою собственную копию myVariable.

//MyHeader.h 
#pragma once 
static int myVariable = 0; 
+0

Спасибо Мохамаду, это имеет смысл. – jpo38

+0

Вы знаете, как предоставить внешнюю связь со статической переменной-членом в статическом lib под Msvc? Или, если невозможно заставить D использовать функцию A, которая уже включена в B или C? –

0

статическая связанная библиотека и статические переменные не связаны.

Статическая переменная не видна за пределами текущей области компиляции (в файле .o нет символьного имени, поэтому никакие другие .o-файлы не могут найти эту переменную через имя символа).

Это означает, что переменная

статический Int Foo; может существовать в каждом объеме компиляции, и каждый из них будет uniqe

0

Ваша статическая переменная действительно статична. Я подозреваю, что даже если (B) ссылки (A), (B) не подбирает свою собственную копию (A), вместо этого она содержит информацию, которую необходимо связать (A).

Это, однако можно компилировать же исходный код с статической переменной в двух библиотеках - например:

test.cpp:

int g_myGlobal = 23; 

и собрать его в (А) и (В) статических библиотек , но затем при связывании всего приложения или dll - вы получите ошибку компоновщика о двойной заданной статической переменной.

Если вы однако объявить переменную с помощью статического ключевого слова:

тест.каст:

static int g_myGlobal = 23; 

Тогда, если же исходный код связан с (А) и (В) - это будет скомпилирована и скомпонована в порядке, но в результате вы будете иметь два экземпляра переменной g_myGlobal (которые могут быть даже другой).

Смежные вопросы