Go to the first, previous, next, last section, table of contents.


Data associated with loaded modules

Some of the internal information about each loaded module that is maintained by libltdl is available to the user, in the form of this structure:

Type: struct lt_dlinfo { char *filename; char *name; int ref_count; }
lt_dlinfo is used to store information about a module. The filename attribute is a null-terminated character string of the real module file name. If the module is a libtool module then name is its module name (e.g. "libfoo" for "dir/libfoo.la"), otherwise it is set to NULL. The ref_count attribute is a reference counter that describes how often the same module is currently loaded.

The following function will return a pointer to libltdl's internal copy of this structure for the given handle:

Function: const lt_dlinfo * lt_dlgetinfo (lt_dlhandle handle)
Return a pointer to a struct that contains some information about the module handle. The contents of the struct must not be modified. Return NULL on failure.

Furthermore, in order to save you from having to keep a list of the handles of all the modules you have loaded, these functions allow you to iterate over libltdl's list of loaded modules:

Function: int lt_dlforeach (int (*func) (lt_dlhandle handle, lt_ptr data), lt_ptr data)
For each loaded module call the function func. The argument handle is the handle of one of the loaded modules, data is the data argument passed to lt_dlforeach. As soon as func returns a non-zero value for one of the handles, lt_dlforeach will stop calling func and immediately return 1. Otherwise 0 is returned.

Function: lt_dlhandle lt_dlhandle_next (lt_dlhandle place)
Iterate over the loaded module handles, returning the first handle in the list if place is NULL, and the next one on subsequent calls. If place is the last element in the list of loaded modules, this function returns NULL.

Of course, you would still need to maintain your own list of loaded module handles to parallel the list maintained by libltdl if there are any other data that you need to associate with each handle for the purposes of your application. However, if you use the following API calls to associate your application data with individual module handles as they are loaded there is actually no need to do that. You must first obtain a unique caller id from libltdl which you subsequently use to retrieve the data you stored earlier. This allows for different libraries that each wish to store their own data against loaded modules to do so without interfering with one another's data.

Type: lt_dlcaller_id
The opaque type used to hold individual data set keys.

Function: lt_dlcaller_id lt_dlcaller_register (void)
Use this to obtain a unique key to store and retrieve individual sets of per module data.

Function: lt_ptr lt_dlcaller_set_data (lt_dlcaller_id key, lt_dlhandle handle, lt_ptr data)
Set data as the set of data uniquely associated with key and handle for later retrieval. This function returns the data previously associated with key and handle if any. A result of 0, may indicate that a diagnostic for the last error (if any) is available from lt_dlerror().

For example, to correctly remove some associated data:

    lt_ptr stale = lt_dlcaller_set_data (key, handle, 0);
    if (stale == NULL)
      {
        char *error_msg = lt_dlerror ();

        if (error_msg != NULL)
          {
            my_error_handler (error_msg);
            return STATUS_FAILED;
          }
      }
    else
      {
        free (stale);
      }

Function: lt_ptr lt_dlcaller_get_data (lt_dlcaller_id key, lt_dlhandle handle)
Return the address of the data associated with key and handle, or else NULL if there is none.

The preceding functions can be combined with lt_dlforeach to implement search and apply operations without the need for your application to track the modules that have been loaded and unloaded:

int
my_dlcaller_callback (lt_dlhandle handle, lt_ptr key_ptr)
{
  struct my_module_data *my_data;

  my_data = lt_dlcaller_get_data (handle, (lt_dlcaller_id) *key_ptr);

  return process (my_data);
}

int
my_dlcaller_foreach (lt_dlcaller_id key)
{
  lt_dlforeach (my_dlcaller_callback, (lt_ptr) &key);
}


Go to the first, previous, next, last section, table of contents.