Widely Vision

Deeper in Libraries With GCC(2)

Posted by aboelnour on February 9, 2010

peace be upon you:

It is a long time since i wrote here. sorry for the few who following this blog :D

In last post we talked about libraries and how to make a static one.

today we will continue our series in the libraries.

———————————–
Example on static libraries:

libhello.c File:

#include <stdio.h>

void hello(void) {
printf(“Hello, library world.\n”);
}

libhello.h File:

void hello(void);

demo_use.c File:

#include “libhello.h”

int main(void) {
hello();
return 0;
}

then run in terminal:

gcc -Wall -g -c -o libhello-static.o libhello.c

to obtain the object file of the source file which we want to make it a library.

ar rcs libhello-static.a libhello-static.o

to create the library.

gcc -Wall -g -c demo_use.c -o demo_use.o

to obtain the object file of the source which use the libarary.

gcc -g -o demo_use_static demo_use.o -L. -lhello-static

to compile the object file with the libarary.

./demo_use_static

to run the program.

and here you can make your own static lib and deal with it.

——————————–

Dynamic Linking:

In the static Linking we locating the library in the linking time this operation done by the linker which called by the compiler.

But there is another technique in linking calling dynamic linking which locating the libraries in the Run Time.

Once a program has been linked to use shared libraries, it must be able to find the shared library when it runs. The libraries are located by name, not by directory.

The loading of the libraries in the run time done by the Operating System.

to make the explanation easy we will start with an Example:

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <dlfcn.h>
  4. int main(int argc, char **argv) {
  5. void *handle;
  6. double (*cosine)(double);
  7. char *error;
  8. handle = dlopen (“/lib/libm.so.6″, RTLD_LAZY);
  9. if(error = dlerror()) {
  10. printf(“%s\n”,error);
  11. exit(1);
  12. }
  13. cosine = dlsym(handle, “cos”);
  14. if(error = dlerror()) {
  15. printf(“%s\n”,error);
  16. exit(1);
  17. }
  18. printf (“%f\n”, (*cosine)(2.0));
  19. dlclose(handle);
  20. }

In this Example we will calculate the cosine of (2.0) using a library called “libm.so.6″ located in /lib.

Explanation of the code:

1-2: We include the standard library and standard I/O library.

3: We include the header dlfcn.h which contain the functions: dlopen(),dlsym(),dlerror(),dlclose() we will explain them later.

5-7: Declaration of void-char pointer 6: Declaration of Function pointer.

8: here we call the dlopen() function which loads the shared library into memory (if it’s not already there) and returns a handle that can be used to address it the first parameter is the library and the second one is a flag  passing to the Operating System.

9-12 ,14-17 : Handle Errors the dlerror() function returns a descriptive string describing the error that occurred on the most recent call to any one of the other functions(dlopen(), dlsym(), dlclose()). The dlerror() function returns NULL if no error occurred.

13: Here we call the dlsym() which return the addresses of the functions the first parameter is the address of the library and the second parameter is the name of the function which you want to use it from the library .

18: here we get the value of the cosine(2) with the function which we get from the library which loaded in the memory.

19: here we call the dlclose() Functions that detaches the current program from the shared library. If no other programs are attached to it,the dynamic library is unloaded from memory.

Note: The flag used as the second argument on the call to dlopen() can be RTLD_NOW,which causes all the functions in the library to be loaded into memory and become immediately available. The other option is to specify RTLD_LAZY, which will delay the actual loading of each function until it is referenced on a call to dlsym(). Either of these flags can be OR‘ed with RTLD_GLOBAL, which allows any external references in this library to be resolved by calling functions found in other (also loaded) dynamic libraries.

to build your program run:

gcc test.c -ldl -o testth

then to run:

./test

the option -ldl indicate that this program will need the Dynamic linker of the OS.

———————————–

so here we are we will cover in the next part how to make your own dynamic library and how to deal with the Environment variables and how to configure your library.

regards,

aboelnour :)

About these ads

3 Responses to “Deeper in Libraries With GCC(2)”

  1. Rania said

    Nice series , keep it up .

    Well,I have a problem in runing dynamic linking example.
    it
    throws
    test.c:(.text+0x1a): undefined reference to `dlopen’
    test.c:(.text+0×23): undefined reference to `dlerror’
    test.c:(.text+0x4f): undefined reference to `dlsym’
    test.c:(.text+0×58): undefined reference to `dlerror’
    test.c:(.text+0x9c): undefined reference to `dlclose’
    collect2: ld returned 1 exit status

    I think it doesn’t link with libm.so.6 , (i have compiled it normally as regular c program …. or should i do some special steps :S )

    Regards,

  2. aboelnour said

    thanks :)

    Actually I forget to add how to run this prog :D I will edit the post now isA.
    you must give the gcc a flag indicate that this program will be use the DL(dynamic linker) of the OS.
    so the run command now will be:

    gcc test.c -ldl -o test

    thanks for reading.

  3. Rania said

    It works.
    Thanks a lot.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: