Jraxon
Jraxon

Reputation: 207

Purpose of using dynamic linking loader <dlfcn.h> instead of direct function call?

I have come across something similar to this piece of code today.

In A.h:

class A { blah blah blah }

#define CREATE_A_FUNC_NAME   ("CreateA")
extern "C" A* CreateA(void);
typedef A* (*funcCreateA)(void);

In main.cpp:

void* handle = dlopen("libA.so", RTLD_LAZY);
funcCreateA func = (funcCreateA)dlsym(handle, CREATE_A_FUNC_NAME);
A* a = func();

Now obviously A.h is only the header for declarations and all its implementations are stored in libA.so.

I have tested that if I set up my project correctly, meaning the lib is correctly linked, I can simply do A* a = CreateA() to get the pointer to a newly created A instance. Hence here come the questions. Why go through so much hassle to achieve something simple as one function call? What is this kind of technology or technique called? What are the pros and cons? When should I use this technique? Thanks!

Upvotes: 0

Views: 2764

Answers (1)

robthebloke
robthebloke

Reputation: 9672

The main reasons to use dlsym rather than linking to the DSO directly:

  • you want to provide a plugin mechanism with your app, so you need to be able to load a DSO on the fly (The plugins aren't known to the linker when you built the exe). The simplest approach for this is to add some virtual base class (I'm assuming 'A' has some virtual methods?), and then export a creator method with "C" linkage (which disables C++ name mangling). It looks as though that's the intent here?
  • You may have code optimised for a specific CPU instruction set (i.e. at startup of a game engine, check which is the latest instruction set the CPU supports, load the relevant SSE or AVX library at runtime, and then call the methods optimised for that particular CPU).
  • In rare cases you might want to 'unload' some heavy code to free up more memory on the device. This happens quite a lot on Android/iOS and consoles (e.g. releasing the shader compiler after all the shaders have been compiled).

It's worth noting that if you link to the DSO directly, under the hood, the linker will simply insert dlsym/dlopen code at app start up, which will automatically load the DSO and resolve the symbols.

Upvotes: 4

Related Questions