Using Dynamic Link Libraries in C Programming on Linux

To facilitate the later upgrade and expansion of program functions, dynamic libraries are often used in program design. This way, the subprogram only loads the dynamic library and uses the functions within it at runtime. Therefore, we usually only need to update the DLL (for Windows systems) or SO (for Linux systems) files to achieve this. Additionally, packaging into a library is beneficial for confidentiality and the accumulation of core technologies. Without further ado, let’s take a look at the relevant content regarding dynamic link libraries on Linux:

1. Header Files and Compilation Options

When operating on the SO dynamic link library under Linux, you need to include #include <dlfcn.h> and use the -ldl option when compiling with gcc.

2. Common Functions

a. void *dlopen(const char *filename, int flag);

This function returns a handle to the dynamic library. The filename is the name of the library, and the common values for flag are as follows (one of these must be used; other flags can be viewed using man dlopen):

RTLD_LAZY: Does not load the functions of the shared library when opening the SO; the specified function is loaded only when dlsym is called;

RTLD_NOW: Loads all functions of the shared library into memory when opening the SO.

b. void *dlsym(void *handle, const char *symbol); This function finds the function pointer named symbol from the handle returned by dlopen and returns it. Note that the return type is void *, which must be typecast.

c. int dlclose(void *handle); Closes the handle opened by dlopen.

d. char *dlerror(void); After the above dynamic link library operation functions are called, calling this function will return NULL if no error occurred. If an error is found, it will return an error string, which is the error message.

3. How to Find Libraries Ignoring the cases of the DT_RPATH and DT_RUNPATH flags in ELF files, the standard library search order is as follows: First, check the directories corresponding to the LD_LIBRARY_PATH environment variable. If not found, check the /etc/ld.so.cache file (maintained and refreshed by the ldconfig command). If still not found, check the /lib and /usr/lib directories.

4. How to Create SO Use the -shared parameter when generating SO with gcc.

With the above basics, let’s learn how to use SO through an example:

slam.c (compiled into slam.so):

#include <stdio.h>
void print(char *str){        printf("%s\n", str);}

cso_exam.c:

#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char * argv[]){        if (argc != 2) {                printf("Usage:%s whattoprint\n", argv[0]);                return 0;        }                void * slam_handle;        void (*print_func)(char * str);                slam_handle = dlopen("slam.so", RTLD_LAZY);        if (!slam_handle) {                printf("dlopen failed.\n");                return -1;        }                print_func = (void (*)(char*))dlsym(slam_handle, "print");        if (dlerror() != NULL) {                printf("dlsym failed.\n");                return -1;        }        (*print_func)(argv[1]);                return 0;}

Makefile:

all:        gcc -o slam.so -shared -fPIC slam.c        gcc -rdynamic -o cso cso_exam.c -ldl
clean:        rm -rf slam.so cso

The corresponding source file directory tree is as follows:

/home/xinu/xinu/c_cpp/c_so_example/ ├── cso_exam.c ├── Makefile └── slam.c 

At this point, all preparations are complete. After running make, the current directory will generate two files: cso and slam.so. To ensure that the program can search for the library in the current directory at runtime, we execute the following command:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. 

Next, running ./cso hello will not prompt for a missing library.

Leave a Comment