środa, 21 czerwca 2023

C - Linux - Tworzenie bibliotek

W tym poście chciałbym opisać sposób na wykonanie własnych bibliotek (shared library) w Linuxie. 


Najpierw tworzymy jakąś przykładową, prostą bibliotekę:

testsl.c

  1. #include <stdio.h>
  2. #include "testsl.h"
  3.  
  4.  
  5. void TestSL_DisplayData(const int32_t data)
  6. {
  7.     printf("delta %d", data);
  8. }
  9.  
  10. double TestSL_CalculateDelta(const int32_t a, const int32_t b, const int32_t c)
  11. {
  12.     return ((b*b) - (4*a*c));
  13. }

testsl.h

  1. #ifndef __TESTSL_h__
  2. #define __TESTSL_h__
  3.  
  4. #include <stdint.h>
  5.  
  6. void TestSL_DisplayData(const int32_t data);
  7. int32_t TestSL_CalculateDelta(const int32_t a, const int32_t b, const int32_t c);
  8.  
  9. #endif  // __TESTSL_h__

Po przygotowaniu plików. Należy je skompilować. 

  1. gcc -Wall -Wextra -Werror -pedantic -fPIC -c testsl.c

Jeśli wszystko przejdzie poprawnie w folderze pojawi się plik testsl.o.

Następnie tworzymy zintegrowaną bibliotekę:

  1. gcc -shared -Wl,-soname,libtestsl.so -o libtestsl.so testsl.o

Teraz powinniśmy dostać w tym samym folderze plik libtestsl.so.

Po stworzonej bibliotece można przejść do przygotowania testowego pliku main:

  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include "testsl.h"
  4.  
  5. int main(void)
  6. {
  7.     printf("test\r\n");
  8.     int32_t delta = TestSL_CalculateDelta(2, 7, 6);
  9.     TestSL_DisplayData(delta);
  10.     printf("\r\nkoniec\r\n");
  11.     return 0;
  12. }

Teraz czas na jego kompilację:

  1. gcc -L/home/<ścieżka do folderu> -Wall -o maintest main.c -ltestsl

Można zmienić nazwę jako PWD. Jeżeli biblioteka jest w tym samym miejscu co plik main:

  1. gcc -L${PWD} main.c -o test2main -ltestsl

Teraz jeśli będziemy chcieli uruchomić stworzoną aplikację to wyświetlony zostanie następujący błąd:

  1. ./test2main: error while loading shared libraries: libtestsl.so: cannot open shared object file: No such file or directory

Wobec tego należy zdefiniować ścieżkę dla zmiennej środowiskowej. Biblioteka jest dołączana dynamicznie.

  1. export LD_LIBRARY_PATH=/home/<ścieżka>/cprogram_test/shared_lib_test:$LD_LIBRARY_PATH

Po ustawieniu można sprawdzić czy wszystko poszło poprawnie:

  1. echo $LD_LIBRARY_PATH

W odpowiedzi powinniśmy otrzymać ścieżkę, którą podaliśmy w poprzedniej komendzie.

Jeśli dane są niepoprawne, lub chcielibyśmy je zmienić, to wykorzystujemy następującą komendę:

  1. unset LD_LIBRARY_PATH

W celu sprawdzenia od jakich bibliotek program jest zależny, należy wywołać następującą komendę:

  1. linux-vdso.so.1 (0x00007ffebf34c000)
  2. libtestsl.so => /home/<sciezka>/libtestsl.so (0x00007feaf8116000)
  3. libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007feaf7d25000)
  4. /lib64/ld-linux-x86-64.so.2 (0x00007feaf851a000)