First, a simple description of the situation: there are three code files, one main executable and two dynamic libraries. The structure is similar to the weak symbol example:
#include <string>
std::string g_name;
void init_name_lib1()
{
g_name = "lib1";
}
const char* get_name_lib1()
{
return g_name.c_str();
}
#include <string>
std::string g_name;
void init_name_lib2()
{
g_name = "lib2";
}
const char* get_name_lib2()
{
return g_name.c_str();
}
#include <iostream>
void init_name_lib1();
void init_name_lib2();
const char* get_name_lib1();
const char* get_name_lib2();
int main()
{
init_name_lib1();
init_name_lib2();
std::cout << "name from lib1: " << get_name_lib1() << std::endl;
std::cout << "name from lib2: " << get_name_lib2() << std::endl;
return EXIT_SUCCESS;
}
Compilation and run commands are basically the same as before:
1986 g++ -c -fpic cpp_lib2.cpp
1987 g++ -c -fpic cpp_lib1.cpp
1988 g++ -shared -o lib1.so cpp_lib1.o
1989 g++ -shared -o lib2.so cpp_lib2.o
1990 g++ -L./ main.cpp -l1 -l2
1991 LD_LIBRARY_PATH=./ ./a.out
After running, both libraries return the same string, ‘lib2’. In some initialization methods, such as using the fmt library, there may even be a double free error when the main program exits. The reason is that on Linux, gcc by default exports all symbols from dynamic libraries. The two different libraries both have a global variable named g_name. When the main program loads, the later one overrides the earlier one. The same applies to functions: if two different dynamic libraries both use the same common code but different versions, one library may malfunction because it ends up calling the wrong version of the function.
Once the cause is understood, the solution is straightforward: rename the symbols, or wrap them in different namespaces, or mark them static so they are hidden inside the object file.
博主友情提示:
如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用>>博主专用加密工具v3<<处理后发布,原文只有博主可以看到。