The Mozilla
Organization
Our Mission
Who We Are
Getting Involved
Community
Editorials
What's New
Development
Roadmap
Module Owners
Blue Sky
Projects
Status
Tools
Products
Source Code
Binaries
Documentation
License Terms
Bug Reports
Search
Feedback


[Contents] [Previous] [Next][Last]


Chapter 19
Dynamic Library Linking

This section describes NSPR's programming interface to load, unload and resolve symbols in dynamic libraries. It also provides a method by which one can condition symbols of statically linked code so that to other clients it appears as though they are dynamically loaded.
  • Types
  • Functions
  • Platform Notes
  • Types

    PRLibrary

    A PRLibrary is an opaque structure. A reference to such a structure may be returned by some of the functions in the runtime and serve to identify a particular instance of a library.
    typedef struct PRLibrary PRLibrary;

    PRStaticLinkTable

    A static link table entry may be created by a client of the runtime so that other clients can access static or dynamic libraries transparently. The basic function on a dynamic library is to acquire a pointer to a function that the library exports. If, during initialization, such entries are manually created, then future attempts to link to the symbols can be treated in a consistent fashion.
    typedef struct PRStaticLinkTable {
        const char *name;
        void (*fp)();
    } PRStaticLinkTable;
    

    Functions

    PR_SetLibraryPath

    For convenience, a default library pathname may be registered with the runtime. This allows an environment to express policy decisions globally and lazily rather than hardcoding and distributing the decisions throughout the code.
    PRStatus PR_SetLibraryPath(const char *path);
    Parameters
    path A pointer to a character array that contains the directory path that the application should use as a default. The syntax of the pathname is not defined, nor whether that pathname should be absolute or relative.
    Result
    This function will fail (return a value of PR_FAILURE) if it cannot allocate sufficient storage to make a copy of the path string.

    PR_GetLibraryPath

    PR_GetLibraryPath() allows the caller to discover the current default.
    char* PR_GetLibraryPath(void);
    Result
    The result is a copy of the library pathname. If sufficient storage cannot be allocated to contain the copy, a NULL will be returned. Storage for the result is allocated by the runtime and becomes the responsibility of the caller. It should be deleted by calling PR_FreeLibraryName().

    PR_GetLibraryName

    Given a directory name and a library name construct a full path name that will refer to the actual dynamically loaded library. This does not test for existence of said file, it just constructs the full filename. The name constructed is system dependent and prepared for PR_LoadLibrary().
    char* PR_GetLibraryName(const char *dir, const char *lib);
    Parameters
    dir A NULL-terminated string representing the path name of the library. A suitable source for this information would be the result of a call to PR_GetLibraryPath().
    lib The leaf name of the library of interest.
    Result
    If the function call is successful, the character array returned is one suitable for use in the PR_LoadLibrary() call. The storage for the result is allocated by the runtime and becomes the responsibility of the caller and must ultimately be deleted by using the PR_FreeLibraryName() function.

    PR_GetLibraryName() might fail if the runtime cannot allocate sufficient memory for the result. In such cases a NULL will be returned.

    PR_FreeLibraryName

    PR_FreeLibraryName() is available for deleting the storage allocated by the runtime in the functions described previously. It is important to use this function to rather than calling directly into malloc in order to isolate the runtime's semantics regarding storage management.
    void PR_FreeLibraryName(char *mem);
    Parameter
    mem A reference to a character array that was previously allocated by the dynamic library runtime.

    PR_LoadLibrary

    PR_LoadLibrary() attempts to load the referenced library. It will suppress duplicate loading if the library is already known by the runtime.
    PRLibrary* PR_LoadLibrary(const char *name);
    Parameters
    name A platform dependent character array that depicts the library to be loaded. An appropriate source of such an array would be PR_GetLibraryName().
    Results
    If the operation is successful, a reference to an opaque PRLibrary object is returned. This becomes the library's identity. If the library is already known to the runtime, the duplicate loading will be suppressed. Each PR_LoadLibrary() must be paired with a corresponding PR_UnloadLibrary() in order to return the runtime to its original state.

    If the operation fails, a NULL result will be returned. The reason for the failure can be discovered by calling PR_GetError().

    PR_UnloadLibrary

    PR_UnloadLibrary() undoes the effect of a PR_LoadLibrary(). If the function is successful, future references to the library using its identity (PRLibary*) will be invalid.
    PRStatus PR_UnloadLibrary(PRLibrary *lib);

    Parameter

    lib A reference previously returned from PR_LoadLibary().
    Result
    If the function returns a value of PR_FAILURE the library could not be unloaded. The actual reason may be discovered by calling PR_GetError(). Otherwise, future references to the library identified by its PRLibary reference should be considered invalid.

    PR_FindSymbol

    PR_FindSymbol() will return an untyped reference to a symbol in a particular library given the identity of the library and a textual representation of the symbol in question.
    void* PR_FindSymbol(PRLibrary *lib, const char *name);
    Parameters
    lib A valid reference to a loaded library or NULL. This parameter can be acquired only by a call to PR_LoadLibrary(). If this parameter is NULL all libraries known to the runtime and the main program will be searched in an unspecified order.
    name A textual representation of the symbol to resolve.
    Result
    PR_FindSymbol() returns an untyped pointer. Dominant use of the function is expected to be to look up functions in a shared library, though data symbols can also be acquired. Getting a pointer to a symbol in a library does indicate that the library is available when the search was made. The runtime does nothing to insure the continued validity of the symbol. If the library is unloaded (for instance), the results of any FindSymbol() calls become invalid as well.

    PR_FindSymbolAndLibrary

    PR_FindSymbolAndLibrary() finds a symbol in one of the currently loaded libraries. Given the name of a symbol, return the address of the symbol, and the library that contains that symbol, or NULL if no such function can be found. The order that the known libraries are searched in not specified.
    void* PR_FindSymbolAndLibrary(const char *name, PRLibrary **lib);
    Parameters
    name The textual representation of the symbol to locate.
    lib A reference to a location at which the runtime will store the library in which the symbol was discovered.
    Results
    If the symbol could not be found, a NULL is returned. Otherwise, a non-NULL pointer to the symbol will be returned. Also, the owning library's identity will be stored in the location pointed to by the parameter lib. This function is equivalent to first calling PR_LoadLibary() followed by PR_FindSymbol(). The identity returned from PR_FindSymbolAndLibrary() must be the target of a PR_UnloadLibrary() in order to return the runtime to its original state.

    Looking Up Symbols Defined in the Main Executable Program

    PR_LoadLibrary cannot open a handle that references the main executable program. (This is admittedly an omission that should be fixed.) However, it is possible to look up symbols defined in the main executable program as follows.
    PRLibrary *lib;
    void *funcPtr;

    funcPtr = PR_FindSymbolAndLibrary("FunctionName", &lib);

    When PR_FindSymbolInLibrary returns, funcPtr is the value of the function pointer you want to look up, and the variable lib references the main executable program. Then you can call PR_FindSymbol on lib to look up other symbols defined in the main program. Remember to call PR_UnloadLibrary(lib) to close the library handle when you are done.

    PR_LoadStaticLibrary

    The purpose of PR_LoadStaticLibrary() is so that other clients in the process can access static symbols using the same mechanisms as those available for dynamically loaded libraries. Once the static symbols are made known to the runtime (presumably at initialization) the remainder of the application can use the API uniformly, including symbols possibly implemented in the main program.
    PRLibrary* PR_LoadStaticLibrary(
    const char *name, const PRStaticLinkTable *table);
    Parameters
    name The name the caller wishes to associate with the static library. If the value is NULL the symbols will be made available to the library which represents the executable.
    table A reference to the client constructed table containing symbol name and address tuples. The table is not copied by the runtime.
    Result
    If the function call is successful, the new table's identity is returned. In order to return the runtime to its previous state, the identity must be the argument of a PR_UnloadLibarary() call.

    Platform Notes

    On some platforms, in order to use the dynamic library loading functions described in this chapter, certain environment variables must be set at run time, and you may even need to link your executable programs using special linker options.

    This section is a short summary of these platform idiosyncrasies. For more information, please consult the ld and dlopen (or shl_load on HP-UX) manual pages on Unix and the LoadLibrary documentation on Win32.

    Dynamic Library Search Path

    The dynamic library search path is the list of directories in which to look for a dynamic library. Each platform has its own standard directories in which to look for dynamic libraries, plus a customizable list of directories specified by an environment variable.

    On most Unix systems, this environment variable is LD_LIBRARY_PATH. These systems typically use dlopen to load a dynamic library.

    HP-UX uses shl_load to load dynamic libraries, and the environment variable specifying the dynamic library search path is SHLIB_PATH. Moreover, the executable program must be linked with the +s option so that it will search for shared libraries in the directories specified by SHLIB_PATH at run time. Alternatively, you can enable the +s option as a postprocessing step using the chatr tool:
    link your executable program a.out without the +s option
    chatr +s enable a.out

    On Rhapsody, the environment variable is DYLD_LIBRARY_PATH.

    On Win32, the environment variable is PATH. (So the same search path is used to search for executable programs and DLLs.)

    Exporting Symbols From the Main Executable Program

    On some systems, symbols defined in the main executable program are not exported by default. On HP-UX, one must link the executable program with the -E linker option in order to export all symbols in the main program to shared libraries. If you use the GNU s (on any platform), you must also link the executable program with the -E option.

    [Contents] [Previous] [Next][Last]
    Last Updated: Tue Jul 14 17:07:28 PDT 1998
    Copyright © 1998 Netscape Communications Corporation



    Copyright © 1998 The Mozilla Organization.