Weak dependency on a shared library on Linux

I want my executable to be “optionally dependent” on another shared object. Thus, it can work without some characters if there is no DSO.

I can achieve this with calls dlopen/dlsym, but I have to manually load each character and add wrappers for them as follows:

void *my_lib = dlopen("my_lib.so", RTLD_LAZY);  
if (!my_lib)  {
    // ok, I promise not to touch my_lib symbols
} else {
    my_foo_ptr = dlsym(my_lib, "my_foo");
    my_bar_ptr = dlsym(my_lib, "my_bar");
}

... my_foo(...) {
    assert(my_foo_ptr);
    return (*my_foo_ptr)(...);
}

... my_bar(...) {
    assert(my_foo_ptr);
    return (*my_bar_ptr)(...);
}

This is dumb code, and it directly depends on the "my_lib.so" ABI, which means that I have to update it every time I update the library.

I am looking for a way to ld.sodo it for me. Thus, the ideal would be as follows:

void *my_lib = dlopen("my_lib.so", /* bring me all my symbols */);  
if (!my_lib)  {
    // ok, I promise not to touch my_lib symbols
} else {
    // ok, I can directly call symbols from my_lib.so
    my_foo();
    my_bar();
}

: 1. ? my_lib.so, my_lib.so. , ld undefined.
2. dlopen() my_lib.so ?

: , DT_NEEDED . , ld .

+5
3

, , , , . - : , , , . , , , : , , , , , null (, , ). , , .

+3

- apmasell , . , , :

 -Wl,-init,<function name> and -Wl,-fini,<function name>

, init dlsym(). , void init_module(void *handle); ( handle - dlopen), .

+1

, , , , . :

  • GCC , , binutils, "" (.. , , ).

  • You will need to fix the dynamic bootloader to understand your characters.

A simpler approach is probably to use DSL , which a tool (= script or a simple C program) can read and use to create C boiler code for you.

DSL will detect all characters (and parameters), and the tool will convert them to .h and .c files using the above code patterns.

When it my_lib.sochanges (or when you need more characters), you simply edit the (small) DSLs and restart the scripts.

0
source

All Articles