问题描述
我在启用--static-libstdc ++的情况下编译了2个共享库。
这两个共享库具有相同的功能f
,仅将一个字符串和一个整数输出到stdout。
主程序将使用dlopen
加载2个共享库,并使用f
在其中调用dlsym
。
但是,第二个加载的共享库无法输出整数,并且C ++流cout
变为bad & fail
。
ADD:经过讨论,我知道这是正常的...但是,我想将我的问题更改为:libstdc ++的哪种实现导致了此问题?有没有共享的全局状态?我认为,如果没有共享的全局状态,那应该不成问题。我通过静态链接到VCRuntime并使用LoadLibrary在Windows中编写了类似的程序,它可以正常工作。那么为什么libstdc ++是这样设计的?
以下是2个共享库的代码。 (它们共享相同的代码)
他们只会cout
一个字符串和一个整数。
// dll.cpp
#include <iostream>
using namespace std;
extern "C" void f()
{
cout << "hi" << 1 << endl;
bool is_eof = cout.eof();
bool is_fail = cout.fail();
bool is_bad = cout.bad();
cout.clear();
cout << endl;
cout << "eof: " << to_string(is_eof) << endl;
cout << "fail: " << to_string(is_fail) << endl;
cout << "bad: " << to_string(is_bad) << endl;
}
这是主程序,它加载共享库并调用其f
函数。
// main.cpp
#include <iostream>
#include <dlfcn.h>
#include <cassert>
using namespace std;
using fn_t = void(void);
void call_f_in_dll(const char *dll_path)
{
auto dll = dlopen(dll_path,RTLD_LAZY);
assert(dll);
fn_t *fn = (fn_t *)dlsym(dll,"f");
assert(fn);
fn();
dlclose(dll);
}
int main()
{
call_f_in_dll("./libmydll.so");
cout << endl;
call_f_in_dll("./libmydll2.so");
return 0;
}
这是CMakeLists。
# CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project (TestGCC)
add_link_options(-static-libgcc -static-libstdc++)
add_library(mydll SHARED dll.cpp)
add_library(mydll2 SHARED dll.cpp)
add_executable (main main.cpp)
target_link_libraries(main dl)
输出为:
hox@HOX-PC:~/repos/test-gcc/out$ ./main
hi1
eof: 0
fail: 0
bad: 0
hi
eof: 0
fail: 1
bad: 1
请注意第二部分,在
1
和hi
变成fail & bad
之后没有1
。
您可以在此处签出代码:https://github.com/xuhongxu96/dlopen-iostream-issue
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)