Как обрабатываются статические глобалы в нескольких модулях? - PullRequest
0 голосов
/ 06 марта 2012

В C объявление переменной static на глобальном уровне (вне какой-либо функции) означает, что она видна только этому объекту компоновщика (как правило, этому файлу .C).

Если один и тот же файл .C является частью нескольких разных библиотек, которые затем объединяются в один исполняемый файл, возникают ли конфликты?

Например:

MyFile.c

typedef struct {
   [my important data];
} MyGlobalType;

static MyGlobalType globalData = { [...data...] };

Тогда, если у меня есть:

Plugin_Alpha.so : состоит из MyFile.C + AlphaSource.C
Plugin_Beta.so : состоит из MyFile.C + BetaSource.C
MainProgram.exe : состоит из MainCode.C (который загружает два плагина)

Будут ли у Plugin_Alpha и Plugin_Beta отдельные, изолированные копии globalData? Или они в конечном итоге ссылаются на одну и ту же структуру?

1 Ответ

3 голосов
/ 06 марта 2012

Ну, вот один из способов выяснить:

Файл liba.c:

static int globalData;

int *GetGlobalData() { return &globalData; }

Компилировать в две отдельные общие библиотеки:

$ gcc liba.c -o liba.so -fPIC -shared
$ gcc liba.c -o libb.so -fPIC -shared

Основная программа:

#include <dlfcn.h>
#include <stdio.h>

int main(void)
{
  // Error checking omitted for expository purposes

  void *liba = dlopen("liba.so", RTLD_LAZY);
  void *libb = dlopen("libb.so", RTLD_LAZY);

  typedef int* (*FuncV_IP)(void);
  FuncV_IP funca = (FuncV_IP)dlsym(liba, "GetGlobalData");
  FuncV_IP funcb = (FuncV_IP)dlsym(libb, "GetGlobalData");

  printf("Module A: GetGlobalData() ==> %p\n", funca());
  printf("Module B: GetGlobalData() ==> %p\n", funcb());

  dlclose(liba);
  dlclose(libb);

  return 0;
}

Скомпилируйте и запустите:

$ gcc main.c -ldl
$ LD_LIBRARY_PATH=. ./a.out

Выход:

Module A: GetGlobalData() ==> 0x7fa97536d020
Module B: GetGlobalData() ==> 0x7fa97516b020

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

...