dlsym()

Updated: April 19, 2023

Get the address of a symbol in a shared object

Synopsis:

#include <dlfcn.h>

void* dlsym( void* handle, 
             const char* name );

Arguments:

handle
Either a handle for a shared object, returned by dlopen(), or either of the special flags, RTLD_NEXT or RTLD_DEFAULT.
name
The name of the symbol that you want to find in the shared object.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The dlsym() function lets a process obtain the address of the symbol specified by name defined in a shared object.

Note: The dlsym() function is available only to dynamically linked processes.

If handle is a handle returned by dlopen(), you must not have closed that shared object by calling dlclose(). The dlsym() functions also searches for the named symbol in the objects loaded as part of the dependencies for that object.

If handle is RTLD_NEXT, dlsym() searches the objects loaded after the object calling dlsym().

If handle is RTLD_DEFAULT, dlsym() searches all objects in the current process, in load-order.

In the case of both RTLD_NEXT and RTLD_DEFAULT, if the objects being searched were loaded with dlopen(), dlsym() searches the object only if the caller is part of the same dependency hierarchy, or if the object was loaded with global search access (using the RTLD_GLOBAL mode).

Returns:

A pointer to the named symbol for success, or NULL if an error occurs.

Errors:

If an error occurs, more detailed diagnostic information is available from dlerror().

Examples:

Use dlsym() to find a function pointer and a pointer to a global variable in a shared library:

typedef int (*foofunc)( int );

void* handle;
int* some_global_int;
foofunc brain;

/* Open a shared library. */
handle = dlopen( "/usr/nto/x86_86/lib/libfoo.so.1", RTLD_NOW );

/* Find the address of a function and a global integer. */
brain = (foofunc)dlsym( handle, "takeover_world" );
some_global_int = (int* )dlsym( handle, "my_global_int" );

/* Invoke the function and print the int. */
x = (*brain)( 5 );
printf( "that global is %d\n", *some_global_int );

Check to see if a function is defined, and call it if it is:

typedef int (*funcptr)( void );

funcptr funk = NULL;

funk = (funcptr)dlsym( RTLD_DEFAULT, "get_funky" );
if( funk != NULL ) {
    (*funk)();
}

Classification:

POSIX 1003.1

Safety:  
Cancellation point No
Interrupt handler No
Signal handler No
Thread Yes

Caveats:

Function pointers are a pain; use typedefs to help preserve your sanity.