Dynamic Loading of Shared Objects Using Dlopen()

Loading shared library dynamically using dlopen

The reason is that you never allocate any Test object. The pointer is NULL(use nullptr), so

tObj->number = number; is UB and likely a segfault.
There's no reason for test to be a pointer.

Test tMainObj;getAge(&tMainObj,myAge); is simpler and gets the job done.

Does one definition rule apply to dynamically loading shared libraries at runtime?

Objects in a shared library loaded by dlopen do not appear in the namespace of the main program. You need to call dlsym with the name of the object as a string to get a pointer to it.

Using your example of having two libraries dynamically loaded having a global with the same name:

void *lib1 = dlopen("lib1.so", RTLD_LAZY);
int *lib1_global1 = dlsym(lib1, "global1");

void *lib2 = dlopen("lib2.so", RTLD_LAZY);
int *lib2_global1 = dlsym(lib2, "global1");

Here, both lib1.so and lib2.so contain a global variable of type int named global1. Because the dlsym function returns a pointer to the variable/function in question, you can handle this case with no conflict.

Dynamic loading of shared objects using dlopen()

You should dlopen using the library's SONAME. You can see that by using readelf -d [libname].

For example, on one of my Fedora Linux machines the SONAME of the C library is libc.so.6.

The symlinks from the .so names to the .so.6 names are not guaranteed. Those symlinks are only needed for compiling software and are usually not installed on systems without the development packages.

You would not want to end up loading a version with a different number anyway, because the number changes indicate major API differences.

constraints when dynamically loading a shared object from another shared object?

If you dynamically load a DLL you must make sure that it has no unresolved symbols.

The easiest way to do this is to link it against the other DLLs that it needs so that they load automatically rather than you having to load and resolve all dependencies manually.

So if libprofile1 always uses libdatasources make sure they are linked with each other.

If you must do it manually then reverse the order that you load the libraries. So that when you load libprofile1 the functions that it needs have already been loaded.

Linux and shared libraries, linking vs dlopen - symbol visibility

Your question is exceedingly unclear.

If you dlopen the library, then about the only way to get to any of its symbols is via dlsym.

However, if you dlopen a library with RTLD_GLOBAL, then its symbols become available for subsequently loaded libraries without using dlsym.

For example, if libfoo.so defines symbol foo, and if you dlopen("libfoo.so", RTLD_GLOBAL|...); and later dlopen("libbar.so", ...) which uses foo, that would work -- libbar.so will be able to use foo from libfoo.so without doing any dlsym calls.

What are the use cases of dlopen vs standard dynamic linking?

So, are there other uses where dlopen is prefered over the standard dynamic linking/loading?

Typical use-cases for using dlopen are

  • plugins
  • selecting optimal implementation for current CPU (Intel math libraries do this)
  • select implementation of API by different vendors (GLEW and other OpenGL wrappers do this)
  • delay loading of shared library if it's unlikely to be used (this would speed up startup because library constructors won't run + runtime linker would have slightly less work to do)

Avoiding the compiler supervision is unsafe and a good way to write bugs...
We're also missing the potential compiler optimizations.

That's true but you can have best of both worlds by providing a small wrapper library around delay loaded shared library. On Windows this is done by standard tools (google for "DLL import libraries"), on Linux you can do it by hand or use Implib.so.



Related Topics



Leave a reply



Submit