Linux Shared Object Tutorial

linux shared object

Illustration of a program that uses functions from shared objects to play audio (from wikipedia)

Shared object files contain a library of functions that can be used by an executable. When functions are copied from a library into an executable at compile time, source object is called a “static” library. When functions from a library file are linked into an executable at runtime (dynamically), the library is called a shared object because a single dynamic library can be loaded into memory and shared between several executables. In Linux, static libraries are usually given the “.o” extension and shared object files are designated by the “.so” extension. Linux’s shared object files are analogous to Windows DLL files (short for “dynamically linked library”).

Modularity is the primary benefit of shared objects. For instance, one group of programmers can work on the functions contained in a shared object file and another group can work on the code in the main executable. Once the executable is completed, the inner workings of the shared object’s functions can be changed or improved without needing to alter or recompile anything else.

A monolithic executable – no shared objects

The following program implements three functions: add(), subtract() and multiply(). The main functionality of the program is contained in calc.c and the functions are in libcalc.c:

To compile a monolithic executable (no separate shared object file) from these two source files, run gcc and provide both source files as input:

Compiling a Shared Object (.so)

To compile libcalc.c into a separate shared object file, run the following commands:

This will create libcalc.so. The -fPIC flag tells gcc to generate Position Independent Code, which can be loaded and run from anywhere. “ld” then links the static object file (libcalc.o) into the final shared object file. To compile calc.c to use the functions in the libcalc.so shared object:

The -L flag specifies the shared object’s location (in this case, the same directory as the source file). The -l flag specifies the name of the library to be linked during compilation, and is often used in compilation with gcc. -Wl passes -rpath $ORIGIN to the linker. -rpath $ORIGIN tells the final executable to search for libcalc.so in its current directory.

If you’re planning on creating a shared object that will be properly installed into a system’s run-time search path (usually /usr/lib) you may want to omit -Wl,-rpath\$ORIGIN. However, if the development of the executable and its shared object are tightly coupled, locating them in the same folder can be helpful.

A sample shared object project

sharedobject.zip contains a sample shared object project, complete with Makefiles. The shared object code is in the lib/ subdirectory, and the main executable’s code is in calc.c. To make the project, enter the directory and type “make.” To make the shared object without compiling the main executable, enter the lib directory and type “make.”

In the shared object’s source, you may notice that the functions lib_init() and lib_fini() have been commented out. These are the initialization and finalization functions for the shared object. They run when the shared object is loaded and unloaded, respectively:

If you want to run code when the shared object is loaded or unloaded by an executable, uncomment and modify lib_init() and lib_fini() to suit your needs.

Further Reading

Shared objects for the object disoriented!

Dynamic Linking

dlopen(3)

Incoming search terms:

Comments are closed.