【问题标题】:Sharing global data between a shared library and main在共享库和主库之间共享全局数据
【发布时间】:2013-02-21 17:28:25
【问题描述】:

我有一个名为 global_count 的变量,我想在共享库和程序的主要部分(最终还有其他库,但现在我已经简化了测试用例)之间共享它。

鉴于 globals.cpp 中的 global_count 声明:

extern "C" {
  int* global_count;
}    

我们编译创建一个 global.o 文件:

gcc -c global.cpp

shared.cpp 下面将用于创建shared.so

#include <stdio.h>
#include "global.h"

extern "C" {


void init_global_count(int* xp) {
  printf("Initialize global count to: %d\n", *xp);
  global_count = xp;  
};

void print_global_count(){  
  if(global_count) {
    printf("global_count is: %d\n",*global_count);   
  } else {
    printf("global_count* is not initialized!\n");
  }
};
}

global.h:

extern "C" {
extern int* global_count;
}

main.cpp:

#include <stdlib.h>
#include <dlfcn.h>
#include <stdio.h>
#include "global.h"

int answer = 42;
int* gc_copy;

typedef void (*func)();
void (*init_global_count)(int*);
void (*print_global_count)();

void load(char* shared_lib){
  void* handle;  
  handle = dlopen(shared_lib,RTLD_NOW | RTLD_GLOBAL) ;
  printf("load:after dlopen\n");
  if(!handle)
  {
    printf("DID NOT LOAD!\n");
    fflush(stdout);
    fputs (dlerror(), stderr);
    exit(1);
  } else {
    printf("Loaded OK!\n");
    fflush(stdout);

    void (*init_global_count)(int*) = (void (*)(int*))dlsym(handle, "init_global_count"); 
    (*init_global_count)(&answer);
    void (*print_global_count)() = (void (*)())dlsym(handle, "print_global_count");
    (*print_global_count)();
  }
}

int main(){
  printf("main...\n");
  load((char*)"./shared.so");
  if(global_count)
    printf("main:global_count is: %d\n", *global_count);
  return 0;
}

编译共享库和主库:

gcc -g -Wall -fno-omit-frame-pointer -fPIC -shared -o shared.so shared.cpp global.o
gcc -g -o main main.cpp global.o -ldl

请注意,我们在这两个编译中都在 global.o 中进行了链接。

现在我们运行它,输出是:

main...
load:after dlopen
Loaded OK!
Initialize global count to: 42
global_count is: 42

所以从 *print_global_count()* 内部报告的 *global_count*(在 shared.cpp 中定义)如预期的那样是 42。但是,由于 global_count 指针尚未初始化,因此 main 不会报告 global_count - 因此 main.cpp 中的 global_count 与 shared.cpp 中的 global_count 不同。

我想知道是否可以在这里做我想做的事情(在 .so 和加载 .so 的模块之间共享一些全局数据)?如果是这样,我需要不同的链接吗?

【问题讨论】:

  • 尝试使用 'volatile' 关键字声明 global_count。
  • @Peter:好的,我尝试在 global.cpp 文件中的声明前面放置 'volatile' 并重新编译所有内容。从 main 函数读取时 global_count 仍然为 0,所以它似乎没有效果。

标签: c++ c linker global-variables shared-libraries


【解决方案1】:

共享库中的所有对象都需要编译为位置无关(-fpic-fPIC)。因此,将globals.o 链接到您的共享库是错误的。

您实际上是在创建global_count 指针的两个实例。您正在尝试将指针值打印为来自main 的十进制整数。 main版本中的全局指针变量global_count还没有初始化,所以所有字节的起始值都设置为0

您可以从共享库中删除globals.o,并且在main 中只有一个global_count 变量实例。但是,要让共享库看到main 全局变量,必须使它们对它们可见。您可以通过在main 的链接行中将-rdynamic 添加到gcc 的标志来做到这一点。

【讨论】:

  • "您正试图将指针值打印为 main 中的十进制整数。"啊,是的,没错。我试图避免那里出现核心转储,并想看看是否设置了指针。
猜你喜欢
  • 2013-05-19
  • 1970-01-01
  • 1970-01-01
  • 2013-08-03
  • 2011-06-30
  • 1970-01-01
  • 2021-09-28
  • 1970-01-01
  • 2012-01-11
相关资源
最近更新 更多