next up previous
Next: PIC code Up: Unix & Linux Previous: Write the contructor and

dlopen

function dlopen,dlclose, dlsym are actaully the programming interface to the dynamic linker/loader; Assuming we have a function, whose signature is
int foo(int);
We can write a program to invoke the function even when at the compiling time we have no idea which implemenation of the function will be used at run-time; That means the symbol resolution and code loading only happen at running-time. For example , the main.c program is shown below:
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char* argv[]) 
{
    
    if (argc != 2) {
        printf("Usage: <path of shared library>");
        return 0;
    }
    
    void *handle = dlopen(argv[1],RTLD_LAZY);
    if (!handle) {
        fprintf(stderr, "%s\n", dlerror());
        return 0;
    }

    dlerror();                  /* clear any existing error */
    
    int (*foo)(int);
    foo = (int (*)(int)) dlsym(handle,"foo");

    char* error;
    
    if ((error = dlerror()) != NULL){
        fprintf(stderr, "%s\n",error);
        return 1;
    }
    
    printf("%d\n",(*foo)(3));
    dlclose(handle);
    return 0;
}

To invoke dlsym

foo = (int (*)(int)) dlsym(handle,"foo");
we should be careful about the name we are using to indicate the function. Here we assuming the C linkage is used so the name will be just ``foo''. But if the implemenation is using C++ linkage, the C++ name mangling will change the name to be some sort like "_Z3fooi", so the dlsym call will be changed to be
foo = (int (*)(int)) dlsym(handle,"_Z3fooi");
More about C++ mangling can be found at [*]. Now compile the main.c file with ``-ldl'' (Note we don't need specify the location of the library by ``-L'', since at this time we don't idea which library will be used eventually)
 g++ -o main dyn_main.c -ldl

Now assuming we have an implemenation of the function foo in foo_a.c

int foo(int a) 
{
    return a + 1;
}
and we compile it to be a shared library by
 g++ -o libfoo_a.so foo_a.o -shared -Wl,-soname="libfoo_a.so"
Now we can run the main by specifying which library is supposed to used
 ./main ./libfoo_a.so

The -rdynamic option is used to force the linker the create the global symbol table and export all of its global variables into the global symbol table. This options is not for compilation, it is for linking. But unlike -Wl option, which passes the following options to the linker, -rdynamimc is a higher level option and differs according different platforms. In linux, it is just the -export-dynamic option for the linker. -export-dynamic

From the man page of ld
\begin{quot}
\par
When creating a dynamically linked executable, add all symbols...
...ill probably need to use this option when
linking the program itself.
\end{quot}


next up previous
Next: PIC code Up: Unix & Linux Previous: Write the contructor and
Wei Lu 2007-11-06