I step into this problem accidentally.
// foo.cpp
#include <iostream>
int i;
extern "C" {
void pn() {
std::cout << "Hello!" << std::endl;
}
}
I compiled foo.cpp
into foo.so
using gcc:
gcc -fPIC --shared foo.cpp -o libfoo.so
Then there is bar.cpp
.
// bar.cpp
#include <dlfcn.h>
#include <stdio.h>
#include <iostream>
using namespace std;
extern "C" {
int decode();
}
int decode() {
void *handle = dlopen("libfoo.so", RTLD_LAZY);
if (!handle) {
printf("%s \n", dlerror());
return 1;
}
void (*pn)() = (void (*)()) dlsym(handle, "pn");
(*pn)();
return 0;
}
bar.cpp
was compiled into libbar.so
, using g++.
g++ -fPIC --shared -L. -Wl,-R. bar.cpp -lfoo -ldl -o libbar.so
decode
is called in main.cpp
.
// main.cpp
#include <dlfcn.h>
#include <stdio.h>
// Magic sauce
//#include <iostream>
//using namespace std;
int main() {
void *handle = dlopen("libbar.so", RTLD_LAZY);
if (!handle) {
printf("%s \n", dlerror());
return 1;
}
int (*pn)() = (int (*)()) dlsym(handle, "decode");
(*pn)();
return 0;
}
main.cpp
is compiled into executable main
.
g++ -L. -Wl,-R. main.cpp -lbar -ldl -lstdc++ -o main
I used ldd to check libfoo
's dependencies.
linux-vdso.so.1 => (0x00007ffd5b75e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2d9677a000)
/lib64/ld-linux-x86-64.so.2 (0x0000563d0c838000)
If I use iostream
in main.cpp
, which cause main to depend on libstdc++.so
. Then this main
runs without any problem. But if main
does not contain that c++ usage, the executable breaks.
./libfoo.so: undefined symbol: _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
I have been struggled for three days. Wound appreciate any help.
I know that compile foo.cpp
using g++
is the righteous choice. I'm just trying to understand what's happening here.