How do I load a shared object in C++?
There are two ways of loading shared objects in C++
For either of these methods you would always need the header file for the object you want to use. The header will contain the definitions of the classes or objects you want to use in your code.
Statically:
#include "blah.h"
int main()
{
ClassFromBlah a;
a.DoSomething();
}
gcc yourfile.cpp -lblah
Dynamically (In Linux):
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
void *handle;
double (*cosine)(double);
char *error;
handle = dlopen ("libm.so", RTLD_LAZY);
if (!handle) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
dlerror(); /* Clear any existing error */
cosine = dlsym(handle, "cos");
if ((error = dlerror()) != NULL) {
fprintf (stderr, "%s\n", error);
exit(1);
}
printf ("%f\n", (*cosine)(2.0));
dlclose(handle);
return 0;
}
*Stolen from dlopen Linux man page
The process under windows or any other platform is the same, just replace dlopen with the platforms version of dynamic symbol searching.
For the dynamic method to work, all symbols you want to import/export must have extern'd C linkage.
There are some words Here about when to use static and when to use dynamic linking.
(solved) C++ Load one Shared Object with dependencies and access their functions
As a start, change the order of the arguments in the link-commands
g++ -g -shared -o libtest2.so -L. lib2.o -ltest1
g++ -g -shared -o libtest3.so -L. lib3.o -ltest1 -ltest2
Note: it's not necessary with every linker, but the newer gold
linker only resolves "from-left-to-right". Also there's a -Wl,--no-undefined
option, which is very useful to catch these error.
Then add rpath
into these commands so that the shared objects find their dependencies run-time:
g++ -g -shared -o libtest2.so "-Wl,-rpath,${PWD}" -L. lib2.o -ltest1
g++ -g -shared -o libtest3.so "-Wl,-rpath,${PWD}" -L. lib3.o -ltest1 -ltest2
After linkage, readelf -d
should show the RPATH like this:
$ readelf -d libtest3.so |head -n10
Dynamic section at offset 0xdd8 contains 28 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libtest1.so]
0x0000000000000001 (NEEDED) Shared library: [libtest2.so]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000001d (RUNPATH) Library runpath: [/home/projects/proba/CatMan]
(Also there is libtool to deal with shared libraries.)
Mind you, because of name-mangling, the following change should be performed (though it is compiler-specific)
- OpenSymbol(pHandle, "printBase");
+ OpenSymbol(pHandle, "_ZN4Base9printBaseEv");
How can a shared library (.so) call a function that is implemented in its loader code?
You'll need make a register function in your .so so that the executable can give a function pointer to your .so for it's later used.
Like this:
void in_main_func () {
// this is the function that need to be called from a .so
}
void (*register_function)(void(*)());
void *handle = dlopen("libmylib.so");
register_function = dlsym(handle, "register_function");
register_function(in_main_func);
the register_function needs to store the function pointer in a variable in the .so where the other function in the .so can find it.
Your mylib.c would the need to look something like this:
void (*callback)() = NULL;
void register_function( void (*in_main_func)())
{
callback = in_main_func;
}
void function_needing_callback()
{
callback();
}
Loading shared library twice
You need to use dlmopen to achieve this sort of isolation:
// No need for RTLD_LOCAL, not sure about RTLD_DEEPBIND
lib1 = dlmopen (LM_ID_NEWLM, "mylib.so", RTLD_LAZY | RTLD_DEEPBIND);
How to load a shared library without loading its dependencies?
Well, variables are still resolved even with RTLD_LAZY
, so in general you do need all the libraries to be linked. Seems like you should create a stub libbar.so.1
that has no functionality and can be found by the linker.
Is there a way to load a Linux shared library into a specific memory location?
I think that the prelink program may actually demonstrate a way to do this if you are willing to modify the library. The goal is to modify the library so that it will have a preferred address. The intent of prelink is to do this for performance, but my suspicion is that it can be modified to work for your use case.
Note that you will never be guaranteed that this will happen in the general case, but in controlled cases you may be able to guarantee that it will happen.
Certainly examining prelink will allow you to understand the parts of elf involved and make a more informed determination about whether it is possible.
http://en.wikipedia.org/wiki/Prelink#
Or see http://packages.qa.debian.org/prelink for the sources in Debian.
Related Topics
How to Load a Shared Object in C++
Including C Headers Inside a C++ Program
How to Draw Text with Glut/Opengl in C++
Calling Assignment Operator in Copy Constructor
Refreshing the Auto Complete (Intellisense) Database in Visual Studio
Detecting Usb Insertion/Removal Events in Windows Using C++
Friend Class with Limited Access
How to Programmatically Create a Shortcut Using Win32
If I Do a 'Typedef' in C or C++, When Should I Add '_T' at the End of Typedef'Ed Type
Using Createwindowex to Make a Message-Only Window
Fastest Algorithm for Primality Test
Visual Studio: Run C++ Project Post-Build Event Even If Project Is Up-To-Date