Dynamic loaded libraries and shared global symbols

北慕城南 提交于 2019-12-03 07:25:23
g++ -Wall -g -ldl -rdynamic client.cpp libbase.a -o client

CMake adds -rdynamic option allowing loaded library to resolve symbols in the loading executable... So you can see that this is what you don't want. Without this option it just misses this symbol by accident.

But... You should not do any stuff like that there. Your libraries and executable should not share symbols unless they are really should be shared.

Always think of dynamic linking as static linking.

If using shared libraries you must define the stuff you want to export with macro like here. See DLL_PUBLIC macro definition in there.

By default, the linker won't combine a global variable (a 'D') in the base executable with one in a shared library. The base executable is special. There might be an obscure way to do this with one of those obscure control files that ld reads, but I sort of doubt it.

--export-dynamic will cause a.out 'D' symbols to be available to shared libs.

However, consider the process. Step 1: you create a DSO from a .o with a 'U' and a .a with a 'D'. So, the linker incorporates the symbol in the DSO. Step 2, you create the executable with a 'U' in one of the .o files, and 'D' in both a .a and the DSO. It will try to resolve using the left-to-right rule.

Variables, as opposed to functions, pose certain difficulties for the linker across modules in any case. A better practice is to avoid global var references across module boundaries, and use function calls. However, that would still fail for you if you put the same function in both the base executable and a shared lib.

My first question is if there is any particular reason for which you both statically and dynamically (via dlopen) link the same code?

For your problem: -rdynamic will export the symbols from your program and what probably is happening is that dynamic linker resolves all references to your global variable to the first symbol it encounters in symbol tables. Which one is that I don't know.

EDIT: given your purpose I would link your program that way:

g++ -Wall -g -ldl client.cpp -llibrary -L. -o client

You may need to fix the order.

I would advise to use a dlopen(... RTLD_LAZY|RTLD_GLOBAL); to merge global symbol tables.

I would propose to compile any .a static library which you plan to link to a dinamic library, with -fvisibility=hidden parameter, so:

g++ -Wall -fvisibility=hidden -g -c base.cpp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!