--static-libstdc ++를 활성화하여 2 개의 공유 라이브러리를 컴파일했습니다.
2 개의 공유 라이브러리는 동일한 함수를 가지며, f
문자열과 정수를 stdout에 출력합니다.
주요 프로그램은 사용이 공유 libs와로드 dlopen
, 그리고 전화 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
마지막으로 Linux (GNU 확장)에서 문제를 해결하는 방법을 찾았습니다.
dlmopen
더 나은 격리 btw 객체를 제공하는 사용 .
auto dll = dlmopen(LM_ID_NEWLM, dll_path, RTLD_LAZY);
모든 댓글 작성자에게 감사드립니다!
갈등 상태에 대한 자세한 설명을 환영합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다