tl;dr
When the main application makes use of a dynamic library via dlopen
and dlsym
, does it need to be linked against it in any way?
Say I have a library like this,
- header
#pragma once void foo();
- implementation
#include "MyLib.hpp" #include <iostream> void foo() { std::cout << "Hello world, dynamic library speaking" << std::endl; }
that I compile via
g -fPIC -shared MyLib.cpp -o libMyLib.so
If the main application simply uses a symbol exported by that library, e.g.
#include "MyLib.hpp"
#include <iostream>
int main() {
int x;
std::cin >> x;
std::cout << "before calling foo" << std::endl;
foo();
}
that means I have to link it against the library, i.e.
g -c main.cpp -o main.o
g -L. -lMyLib main.o -o main
There are two things that puzzle me:
The first one is: why do I need to link
main.o
againstlibMyLib.so
? I mean, the headerMyLib.hpp
already providesmain.cpp
with the signature offoo
. What is the role of linking in this case?And what about the case that the main application uses
dlopen
to load the library anddlsym
to load symbols from within it?My understanding is that it still needs to
#include "MyLib.hpp"
, for the simple fact that it needs to know how to interpret the output ofdlsym
, but doesmain.o
need to be in anyway linked against the shared object?
CodePudding user response:
If you use dlopen
and dlsym
you don't need the header file or the foo
function prototype. You don't need it because the name in the library will not be plain foo
.
The C compiler uses name mangling to be able to handle things like function overloads, and it's the mangled name you need to pass to dlsym
to get a pointer to the function. The mangled names are very implementation-specific, and you need to examine the library to find out the actual mangled name.
As a workaround for the name mangling problem, you can declare the function in the library as extern "C"
. This will, among other things, inhibit name mangling and you can pass the name foo
to dlsym
.
Also, if you uses dlopen
and dlsym
you should not link with the library. That kind of defeats the purpose of your application doing the dynamic linking.