Load Dynamic link library--dlopen dlsym dlclose

Source: Internet
Author: User
Tags posix

DLOPEN? Dlmopen? Dlclosename

???? Dlclose, Dlopen, Dlmopen -open/close shared objects

Synopsis
#include <dlfcn.h>void *dlopen(const char *filename, int flags);int dlclose(void *handle);#define _GNU_SOURCE#include <dlfcn.h>void *dlmopen (Lmid_t lmid, const char *filename, int flags);
Descriptiondlopen ()

???? This function loads a dynamic shared object (shared library) file named after a null-terminated string file name, and returns an opaque "handle" for the loaded object. This handle is used with other functions in the Dlopen API, for example dlsym() , dladdr() , dlinfo() and dlclose() .

If filename is NULL, the returned handle is used for the main program. If filename contains a slash ("/"), it is interpreted as a (relative or absolute) path name. Otherwise, the dynamic linker will search for objects as follows (for more information, see ld.so(8) ):

    • (Elf only) if the calling program's executable file contains a Dt_rpath tag and does not contain a dt_runpath tag, the directory listed in the dt_rpath tag is searched.
    • If the environment variable LD_LIBRARY_PATH is defined to contain a colon-delimited list of directories when the program starts, the directories are searched. (as a security measure, the Set-user-id and Set-group-id programs will ignore this variable.) )
    • (Elf only) if the executable file of the calling program contains the Dt_runpath tag, the directory listed in the tag is searched.
    • Check the cache file/etc/ld.so.cache (maintained by Ldconfig (8)) to see if it contains an entry for filename.
    • Search Directories/lib and/usr/lib (in this order).

???? If the object specified by filename is dependent on other shared objects, the dynamic linker also automatically loads the objects using the same rules. (This procedure can occur recursively if these objects have dependencies in turn)

The flags parameter must include one of the following two values:

    • Rtld_lazy
      Performs a deferred binding. The symbols are parsed only when the code that references them is executed. If the symbol is never referenced, it is never parsed (deferred binding is performed only on the function reference; When the shared object is loaded, the reference to the variable is always immediately bound). From glibc 2.1.1, this flag is overridden by the effect of ld_bind_now environment variables.
    • Rtld_now
      If this value is specified, or if the environment variable ld_bind_now is set to a non-empty string, dlopen() all undefined symbols in the shared object are resolved before being returned. If this operation cannot be performed, an error is returned.

flags can also be set by the following 0 or more values:

    • Rtld_global
      The symbols defined by this shared object will be available for symbolic resolution of subsequent loaded shared objects.
    • Rtld_local
      This is the default value, in contrast to Rtld_global , if no flag is specified. The symbols defined in this shared object are not available for resolving references in subsequent loaded shared objects.
    • Rtld_nodelete (since glibc 2.2)
      dlclose()do not uninstall shared objects during the period. Therefore, if you later use the dlopen() reload object, the static variables of the object are not reinitialized.
    • Rtld_noload (since glibc 2.2)
      Do not load shared objects. This can be used to test whether the object already resides (if not, dlopen() returns NULL if it is resident and returns a handle to the object). This flag can also be used to promote flags on shared objects that have already been loaded. For example, a shared object that was previously loaded with rtld_local can use rtld_noload | Rtld_global re-open.
    • Rtld_deepbind (since glibc 2.3.4)
      Place the lookup range of the symbol before the global scope of this shared object. This means that self-contained objects will take precedence over their own symbols, rather than global symbols, which are included in the loaded object.
Dlmopen ()

???? This function performs the same task in addition to the following points and dlopen() differences.
????dlmopen() dlopen()The main difference is that it accepts another parameter, lmid, which specifies the list of link mappings (also known as namespaces) of the shared object that should be loaded. For namespaces,lmid_t is an opaque handle.
The lmid parameter is either the ID of the namespace that already exists (this namespace can be dlinfo RTLD_DI_LMID obtained by request) or one of the following special values:

    • Lm_id_base
      Loads the shared object (that is, the application's namespace) in the initial namespace.
    • Lm_id_newlm
      Creates a new namespace and loads the shared object in the namespace. The object must be correctly linked to a shared object that references all other needs because the new namespace is initially empty.

If filename is NULL, then the value of Lmid can only be lm_id_base.

Dlclose ()

????dlclose() Reduces the reference count of dynamically loaded shared objects that are referenced by the specified handle handle . If the reference count is reduced to 0, then this dynamically loaded shared object will be really unloaded. All dlopen() shared objects that are automatically loaded when they are called will be closed recursively in the same way.

????dlclose() A successful return does not guarantee that the symbol associated with the handle will be removed from the caller's address space. dlopen()some shared objects may have been implicitly loaded (and reference counts) as dependencies, in addition to the references that are explicitly generated by the call. The shared object can be removed from the address space only if all references have been disposed.

RETURN VALUE

???? When execution succeeds, dlopen() and dlmopen() returns a non-empty handle.
???? When execution fails (the file cannot be found, is unreadable, the error is in the wrong format, or an error occurs while loading), dlopen() and dlmopen() returns NULL.
???? For dlclose() successful execution, a value of 0 is returned, and a non-0 value is returned when the failure occurs.

The errors generated by these functions can be learned by the error message dlerror() .

Notesdlmopen () and namespaces

???? The link map list defines the orphaned namespaces for symbols resolved through the dynamic linker. Within a namespace, dependent shared objects are implicitly loaded according to the usual rules, and symbolic references are parsed as usual. However, this scenario is limited by the definition of an object that has been (explicitly and implicitly) loaded into the namespace.

????dlmopen() The function allows the object to be loaded in isolation--loads the shared object in the new namespace without exposing the remaining symbols applied to the new object. Note Using the rtld_local flag is not sufficient for this purpose because it prevents the symbol of a shared object from being available to any other shared object. In some cases, we might want to make the symbols provided by some dynamically loaded shared objects available to other shared objects without exposing the symbols to the entire app. This can be done by using a separate namespace and the rtld_global flag.

????dlmopen() Functions can provide better isolation than the rtld_local flag. In particular, when a shared object is loaded through the rtld_local flag and its dependent shared objects are loaded through Rtld_global , it is possible to upgrade to Rtld_global. Therefore, in this case, thertld_local is not sufficient to isolate the loaded shared object, specifically controlling the dependency of all shared objects.

????dlmopen() One use of a function is to load the same object multiple times. If you do not use dlmopen() a function to do this, you need to create a copy of the shared object. If implemented using dlmopen() functions, you can do this by loading the same shared object file into a different namespace.
The GLIBC implementation supports a maximum of 16 namespaces.

Initialization and finalization functions

???? Shared objects can use attribute ((constructor)) and attribute ((destructor)) function Properties. The constructor dlopen() executes before returning, and the destructor dlclose() executes before returning. A shared object can export multiple constructors and destructors and the precedence order can be associated with each function to determine their order of execution.

Dlsymname

???? Dlsym, Dlvsym -Gets the address of a symbol in a shared object or executable file

Synopsis
#include <dlfcn.h>void *dlsym(void *handle, const char *symbol);#define _GNU_SOURCE#include <dlfcn.h>void *dlvsym(void *handle, char *symbol, char *version);
DESCRIPTION

????dlsym() Accepts the dlopen() "handle" of the shared object that is loaded dynamically by the return and returns the address that the symbol is loaded into memory. If no symbol is found, NULL is returned in the specified object or in any shared object that is automatically loaded when the object is loaded dlopen() dlsym() . ( dlsym() a width-first search is made through the dependency tree of these shared objects.) )
???? Because the symbol itself may be null (so dlsym() returning null does not mean an error), the correct way to judge whether the error is wrong is to call dlerror() clear any old error condition, then call dlsym() , and call again dlerror() , save its return value, and determine whether this saved value is Null.
???? You can specify two special pseudo-handles in a handle:

    • Rtld_default
      Finds the first occurrence of a desired symbol using the default shared object search order. The search will include the global symbols in the executable and their dependencies, as well as symbols in shared objects that are dynamically loaded using the rtld_global flag.
    • Rtld_next
      Finds the next desired symbol in the search order after the current object. This allows people to provide a wrapper for a function in another shared object, so, for example, a function definition in a preloaded shared object (see ld_preloadin ld.so (8)) can find and invoke the "real" provided in another shared object function (or, in this case, the "next" definition of the function in the presence of multiple preloaded layers).

????dlvsym() In addition to dlsym() providing an extra parameter than more, the rest is identical to the other dlsym() .

RETURN VALUE

???? Successful execution, these functions will return the address associated with the symbol . Execution fails, they will return NULL. The cause of the error can be dlerror() diagnosed by.

EXAMPLE
#include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include <gnu/lib-names.h>/* defines    Libm_so (which would be a string such as "Libm.so.6") */intmain (void) {void *handle;    Double (*cosine) (double);    Char *error;    Handle = Dlopen (Libm_so, Rtld_lazy);       if (!handle) {fprintf (stderr, "%s\n", Dlerror ());    Exit (Exit_failure);    } dlerror ();    /* Clear Any existing error */cosine = (double (*) (double)) Dlsym (handle, "cos");  /* According to the ISO-C standard, casting between function pointers and ' void * ', as-done above, produces undefined      Results. Posix.1-2003 and Posix.1-2008 accepted this state of affairs and proposed the following workaround: * (void *      *) (&cosine) = Dlsym (handle, "cos");      This (clumsy) cast conforms with the ISO C Standard and would avoid any compiler warnings.      The Technical Corrigendum to Posix.1-2008 (a.k.a. posix.1-2013) ImproVED matters by requiring this conforming implementations support casting ' void * ' to a function pointer. Nevertheless, some compilers (e.g., gcc with the '-pedantic ' option) could complain about the cast used .    */error = Dlerror ();       if (Error! = NULL) {fprintf (stderr, "%s\n", error);    Exit (Exit_failure);    } printf ("%f\n", (*cosine) (2.0));    Dlclose (handle); Exit (exit_success);}

Load the dynamic-link library--dlopen dlsym dlclose

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.