在我的程序中更改共享库中定义的变量不会从共享库中反映出来
Changing the variable defined in shared library in my program doesn't get reflected seen from the shared library
尝试测试一个简单的情况,即共享库中定义的全局变量由程序设置并由共享库使用,我看到了一个奇怪的问题。这是程序代码。
bar.cpp
#include <stdint.h>
#include <stdio.h>
extern "C" {
uint64_t var_from_lib;
}
class BC;
class BC {
public:
void bar(void);
BC();
~BC();
};
BC::BC()
{
}
BC::~BC()
{
}
void BC::bar(void)
{
printf("class function : var_from_lib = %lx\n", var_from_lib);
}
extern "C" {
void bar(void)
{
printf("global function : var_from_lib = %lx\n", var_from_lib);
BC tmp;
tmp.bar();
}
}
main1.c
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
extern uint64_t var_from_lib;
int main1(void)
{
void * dlh = dlopen("./libbar.so", RTLD_NOW);
if (!dlh) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
void (*bar)(void) = dlsym(dlh,"bar");
if (!bar) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
var_from_lib = 0x12341111;
bar();
return 0;
}
main2.c
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
extern uint64_t var_from_lib;
int main2(void)
{
void * dlh = dlopen("./libbar.so", RTLD_NOW);
if (!dlh) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
void (*bar)(void) = dlsym(dlh,"bar");
if (!bar) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
var_from_lib = 0x12342222;
bar();
return 0;
}
main.c
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
extern uint64_t var_from_lib; // = 0x12345678;
uint64_t __attribute__((weak)) var_from_lib; // = 0x12345678;
extern int main1();
extern int main2();
int main(int argc, char *argv[])
{
if (atoi(argv[1]) == 1) {
main1();
}
else if (atoi(argv[1]) == 2) {
main2();
}
else {
printf("usage : main [1|2]\n");
}
return 0;
}
Makefile
.PHONY: all clean test
LDEXTRAFLAGS ?=
all: prog
%.o: %.c
gcc -c -Wall -fpic -g -o $@ -ldl $<
%.o: %.cpp
g++ -c -Wall -fpic -g -o $@ $<
libbar.so: bar.o
g++ -shared -o $@ $<
prog: main.o main1.o main2.o | libbar.so
gcc $(LDEXTRAFLAGS) -o $@ $^ -ldl
clean:
rm -f *.o *.so prog
这里是构建和执行的结果,和我想的不一样
ckim@ckim-ubuntu:~/testdir$ make
gcc -c -Wall -fpic -g -o main.o -ldl main.c
gcc -c -Wall -fpic -g -o main1.o -ldl main1.c
gcc -c -Wall -fpic -g -o main2.o -ldl main2.c
g++ -c -Wall -fpic -g -o bar.o bar.cpp
g++ -shared -o libbar.so bar.o
gcc -o prog main.o main1.o main2.o -ldl
ckim@ckim-ubuntu:~/testdir$ prog 1
global function : var_from_lib = 0
class function : var_from_lib = 0
main1()
将 var_from_lib
更改为 0x12341111
,main2()
将变量更改为 0x12342222
。我希望从共享库内部观察到更改的值,但事实并非如此!
我使用调试器检查了 var_from_lib
的地址,从 main.c
和 bar.cpp
看到的地址是一样的。这里可能有什么问题?
您似乎没有链接到共享库。您正在 dlopen
-ing 它。
只有当您直接链接到共享库.
时,您的预期行为才会像这样工作
使用 dlopen
您需要自己完成所有工作:使用 dlsym
获取共享库定义的符号的地址。
尝试测试一个简单的情况,即共享库中定义的全局变量由程序设置并由共享库使用,我看到了一个奇怪的问题。这是程序代码。
bar.cpp
#include <stdint.h>
#include <stdio.h>
extern "C" {
uint64_t var_from_lib;
}
class BC;
class BC {
public:
void bar(void);
BC();
~BC();
};
BC::BC()
{
}
BC::~BC()
{
}
void BC::bar(void)
{
printf("class function : var_from_lib = %lx\n", var_from_lib);
}
extern "C" {
void bar(void)
{
printf("global function : var_from_lib = %lx\n", var_from_lib);
BC tmp;
tmp.bar();
}
}
main1.c
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
extern uint64_t var_from_lib;
int main1(void)
{
void * dlh = dlopen("./libbar.so", RTLD_NOW);
if (!dlh) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
void (*bar)(void) = dlsym(dlh,"bar");
if (!bar) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
var_from_lib = 0x12341111;
bar();
return 0;
}
main2.c
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
extern uint64_t var_from_lib;
int main2(void)
{
void * dlh = dlopen("./libbar.so", RTLD_NOW);
if (!dlh) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
void (*bar)(void) = dlsym(dlh,"bar");
if (!bar) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
var_from_lib = 0x12342222;
bar();
return 0;
}
main.c
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
extern uint64_t var_from_lib; // = 0x12345678;
uint64_t __attribute__((weak)) var_from_lib; // = 0x12345678;
extern int main1();
extern int main2();
int main(int argc, char *argv[])
{
if (atoi(argv[1]) == 1) {
main1();
}
else if (atoi(argv[1]) == 2) {
main2();
}
else {
printf("usage : main [1|2]\n");
}
return 0;
}
Makefile
.PHONY: all clean test
LDEXTRAFLAGS ?=
all: prog
%.o: %.c
gcc -c -Wall -fpic -g -o $@ -ldl $<
%.o: %.cpp
g++ -c -Wall -fpic -g -o $@ $<
libbar.so: bar.o
g++ -shared -o $@ $<
prog: main.o main1.o main2.o | libbar.so
gcc $(LDEXTRAFLAGS) -o $@ $^ -ldl
clean:
rm -f *.o *.so prog
这里是构建和执行的结果,和我想的不一样
ckim@ckim-ubuntu:~/testdir$ make
gcc -c -Wall -fpic -g -o main.o -ldl main.c
gcc -c -Wall -fpic -g -o main1.o -ldl main1.c
gcc -c -Wall -fpic -g -o main2.o -ldl main2.c
g++ -c -Wall -fpic -g -o bar.o bar.cpp
g++ -shared -o libbar.so bar.o
gcc -o prog main.o main1.o main2.o -ldl
ckim@ckim-ubuntu:~/testdir$ prog 1
global function : var_from_lib = 0
class function : var_from_lib = 0
main1()
将 var_from_lib
更改为 0x12341111
,main2()
将变量更改为 0x12342222
。我希望从共享库内部观察到更改的值,但事实并非如此!
我使用调试器检查了 var_from_lib
的地址,从 main.c
和 bar.cpp
看到的地址是一样的。这里可能有什么问题?
您似乎没有链接到共享库。您正在 dlopen
-ing 它。
只有当您直接链接到共享库.
时,您的预期行为才会像这样工作使用 dlopen
您需要自己完成所有工作:使用 dlsym
获取共享库定义的符号的地址。