فهرست مندرجات

‌ استفاده از library ها


استفاده از shared library

// man 3 pow
/* pow - power function
 * Math library (libm, -lm)
 * /usr/lib/x86_64-linux-gnu/libm.a
 */
#include <math.h>
double pow(double x, double y);
/* pow.c */
#include <stdio.h>
#include <math.h>
 
int main(void)
{
	double base, exponent;
 
	base = 2;
	exponent = 10;
 
	printf("%f to the power %f is %f\n",
		base, exponent, pow(base, exponent));
	return 0;
}
$ gcc pow.c -lm -o pow
$ ./pow
2.000000 to the power 10.000000 : 1024.000000
/* interest.c */
#include <stdio.h>
#include <math.h>
 
int main(void)
{
    int years = 15; /* The number of years you will
                     * keep the money in the bank
                     * account */
    int savings = 99000; /* The inital amount */
    float interest = 1.5; /* The interest in % */
 
    printf("The total savings after %d years "
        "is %.2f\n", years,
        savings * pow(1+(interest/100), years));
    return 0;
}
$ gcc interest.c -lm -o interest
$ ./interest
The total savings after 15 years is 123772.95

ساخت library شخصی

// prime.h
int isprime(long int number);
// prime.c
int isprime(long int number)
{
        long int j;
        int prime = 1;
 
        for(j=2; j<number/2; j++)
                if(number%j == 0)
                        prime = 0;
 
        if(prime == 1)
                return 1;
        else
                return 0;
}

ساخت object از نوع PIC : Position Independent Code

$ # -Wall -Wextra -pedantic are warning options:
$ gcc -Wall -Wextra -pedantic -fPIC -c prime.c 
$ ls -l prime.o 
-rw-r--r-- 1 pejman pejman 1320 Oct 29 00:06 prime.o

ساخت shared Library

$ # -Wl,... send option to linker
$ # .so : shared object
$ gcc -shared -Wl,-soname,libprime.so -o libprime.so prime.o
$ ls -l libprime.so
-rwxr-xr-x 1 pejman pejman 15528 Oct 29 00:12 libprime.so

استفاده از library شخصی در Home Directory

/* complete version is-it-a-prime.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "prime.h"
 
int main(int argc, char *argv[])
{
   long int num;
 
   /* Only one argument is accepted */
   if (argc != 2)
   {
      fprintf(stderr, "Usage: %s number\n",
         argv[0]);
      return 1;
   }
 
   /* Only numbers 0-9 are accepted */
   if ( strspn(argv[1], "0123456789") !=
      strlen(argv[1]) )
   {
      fprintf(stderr, "Only numeric values are "
         "accepted\n");
      return 1;
   }
 
   num = atol(argv[1]); /* String to long */
   if (isprime(num)) /* Check if num is a prime */
   {
      printf("%ld is a prime\n", num);
   }
   else
   {
      printf("%ld is not a prime\n", num);
   }
 
   return 0;
}

کامپایل و لینک با library شخصی در Home Directory

$ gcc -L${PWD} is-it-a-prime.c -o is-it-a-prime -lprime

فایل is-it-a-prime با library مورد نظر در home directory کامپایل شده ولی ضمن اجرا library در دسترس نیست و error خواهد داد

$ ./is-it-a-prime
./is-it-a-prime: error while loading shared libraries: libprime.so: cannot open shared object file: No such file or directory

می توان library هایی که در دسترس نیستند را به این شکل دید (not found)

$ ldd  is-it-a-prime
     linux-vdso.so.1 (0x00007ffd9dbbb000)
     libprime.so => not found
     libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7e6c6f7000)
     /lib64/ld-linux-x86-64.so.2 (0x00007f7e6c8fd000)

مگر آنکه Home directory به LD_LIBRARY_PATH اضافه شده باشد

$ export LD_LIBRARY_PATH=${PWD}:${LD_LIBRARY_PATH}
$ ./is-it-a-prime
Usage: ./is-it-a-prime number
$ ./is-it-a-prime  11
11 is a prime
$ ./is-it-a-prime  15
15 is not a prime

بررسی مجدد لیست library ها و دردسترس بودن libprime.so

$ ldd is-it-a-prime
     linux-vdso.so.1 (0x00007ffe12eba000)
     libprime.so => /home/pejman/C/libprime.so (0x00007f29a610b000)
     libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f29a5f0c000)
     /lib64/ld-linux-x86-64.so.2 (0x00007f29a6117000)

ساخت library شخصی (خلاصه شده)

/* prime.h */
int isprime(long int number);
/* prime.c */
int isprime(long n)
{
	for(long i=2; i < n/2; i++)
		if(n % i == 0) return 0;
	return 1;
}
/* is-it-a-prime.c */
#include <stdio.h>
#include "prime.h"
 
int main(void)
{
	long int num = 1000024073;
 
	if (isprime(num))
		printf("%ld is a prime\n", num);
	else
		printf("%ld is not a prime\n", num);
 
	return 0;
}
$ gcc -c prime.c -fPIC
$ gcc -shared -Wl,-soname,libprime.so -o libprime.so prime.o
$ gcc is-it-a-prime.c -o is-it-a-prime -lprime -L${PWD}
$ ldd ./is-it-a-prime
     linux-vdso.so.1 (0x00007ffd71144000)
     libprime.so => not found
     libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4d35591000)
     /lib64/ld-linux-x86-64.so.2 (0x00007f4d35797000)
$ export LD_LIBRARY_PATH=${PWD}:${LD_LIBRARY_PATH}
$ ldd ./is-it-a-prime
     linux-vdso.so.1 (0x00007ffd52aa9000)
     libprime.so => /home/pejman/C/test/libprime.so (0x00007f598f2d2000)
     libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f598f0d3000)
     /lib64/ld-linux-x86-64.so.2 (0x00007f598f2de000)
$ ./is-it-a-prime
1000024073 is a prime
$ nm -D ./libprime.so
                 w __cxa_finalize
                 w __gmon_start__
00000000000010f9 T isprime
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
$ objdump -T --demangle libprime.so

libprime.so:     file format elf64-x86-64

DYNAMIC SYMBOL TABLE:
0000000000000000  w   D  *UND*	0000000000000000 __cxa_finalize
0000000000000000  w   D  *UND*	0000000000000000 _ITM_registerTMCloneTable
0000000000000000  w   D  *UND*	0000000000000000 _ITM_deregisterTMCloneTable
0000000000000000  w   D  *UND*	0000000000000000 __gmon_start__
00000000000010f9 g    DF .text	000000000000004e isprime
man libc
man ldd