Скорее всего, вы видите Имя искажения в действии здесь.
Если вы хотите использовать dlopen()
/ dlsym()
с общими библиотеками C ++, вам необходимо:
- объявляет функции, которые вы хотите просмотреть через
dlsym()
, как extern "C" { ... }
, так что компилятор C ++ создает для них незащищенные имена.
Это возможно только в том случае, если функциявы пытаетесь получить доступ к функции, не являющейся членом или статической, и не перегруженной (только одна подпись);C ++ не может создавать неупорядоченные имена в других ситуациях.
Если кто-то запросил компилятор сделать это через extern "C" { ... }
, и возможно создать неупорядоченное имя, оно дословно заканчивается в таблице символов ELF.Затем вы можете найти его, используя dlsym()
точно так же, как и для любой функции C. - Узнайте, как называется искаженное имя функции, и используйте это в своем
dlsym()
звоните.
Последнее вы можете сделать с помощью утилиты nm
.Например:
$ nm libstdc++.a | grep -v '^ ' | grep unexpected
0000000000000000 T __cxa_call_unexpected
0000000000000000 T _ZN10__cxxabiv112__unexpectedEPFvvE
0000000000000000 T _ZSt10unexpectedv
0000000000000000 T _ZSt14set_unexpectedPFvvE
0000000000000000 D _ZN10__cxxabiv120__unexpected_handlerE
Это искаженные имена, которые компилятор C ++ фактически поместил в объект ELF.Если вы используете опцию -C
, чтобы запросить от nm
до demangle имен для вас, вы получите:
$ nm -C libstdc++.a | grep -v '^ ' | grep unexpected
0000000000000000 T __cxa_call_unexpected
0000000000000000 T __cxxabiv1::__unexpected(void (*)())
0000000000000000 T std::unexpected()
0000000000000000 T std::set_unexpected(void (*)())
0000000000000000 D __cxxabiv1::__unexpected_handler
Это означает, что для этой библиотеки, если вы хотитеполучив указатель на std::unexpected()
, вам нужно будет запросить dlsym(hdl, "_ZN10__cxxabiv112__unexpectedEPFvvE");
, чтобы поиск был успешным.