Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
5 семестр / OSiSP_LR_4.doc
Скачиваний:
3
Добавлен:
18.02.2023
Размер:
77.31 Кб
Скачать

Динамические библиотеки (shared).

Динамическая библиотека - библиотека, подключаемая к программе в момент выполнения. Это означает, что при создании библиотеки производится не только ее компиляция, но и линковка с другими, нужными ей, библиотеками (!).

Динамические библиотеки полезны в случаях, если:

- Важно не перекомпилировать всю программу, а только перекомпилировать ту часть, которая реализует определенные функции - тогда эти функции выносятся в динамическую библиотеку.

- Важно использовать в программах на C библиотеки, подготовленные на C++ и при этом избежать лишних трудностей с линковкой программы.

- Кроме того, динамические библиотеки позволяют экономить место на жестком диске и в оперативной памяти, если одна и таже библиотека используется несколькими программами.

В Linux, обычно, динамические библиотеки имеют расширение ".so".

Подготовим исходный код динамической библиотеки (пример на C++).

Исходный код динамической библиотеки по принципам создания ничем (!) не отличается от исходного кода статических библиотек.

Итак, исходный код библиотеки (C++):

#include <iostream>

using namespace std;

#include

extern "C" int hello()

{

cout<<"Hello world!n I'm function hello()"<<endl;

return 0;

}

Сохраните приведенный код в файле dynamic.cpp.

* Кстати, внутри динамической библиотеки вы можете описать следующие функции:

void _init() - будет вызвана при инициализации динамической библиотеки (загрузки ее в память);

void _fini() - будет вызвана при выгрузке из памяти динамической библиотеки.

Компиляция и линковка динамических библиотек.

Получим файл с объектным кодом:

g++ -fPIC -c dynamic.cpp -o dynamic.o

(используйте gcc для программ на С и Assembler'е)

Здесь:

-fPIC - использовать относительную адресацию в переходах подпрограмм - во избежание конфликтов при динамическом связывании.

А теперь из объектного файла получим библиотеку:

g++ -shared -olibdynamic.so dynamic.o

(используйте gcc для программ на С)

libdynamic.so - имя результирующей библиотеки;

-shared - предписывает создать динамическую (т.е. "разделяемую") библиотеку.

* Именуйте динамические библиотеки следующим способом: libNAME.so. Это традиция.

Итак, на выходе мы имеем libdynamic.so - нашу динамическую библиотеку.

Использование динамической библиотеки в программе на C/C++.

Связывание с библиотекой во время компиляции программы (C/C++):

Подготовим исходный код нашей программы:

int main()

{

int x = hello();

printf("Return code: %xn",x);

return 0;

}

Сохраните его в файле Dprogram1.c

ИЛИ

(С++)

#include

extern "C" int hello();

int main()

{

int x = hello();

printf("Return code: %xn",x);

return 0;

}

Сохраните его в файле Dprogram1.cpp

(единственное отличие, как вы можете заметить, в ключевом слове extern)

  • Теперь добьемся того, чтобы система смогла найти нашу библиотеку. Поместим libdynamic.so в один из каталогов:

из списка:

echo $LD_LIBRARY_PATH

/lib

/usr/lib

или из списка:

cat /etc/ld.so.conf

и затем выполните "ldconfig"

  • И, наконец, скомпилируем программу и слинкуем ее с библиотекой:

gcc ИСХОДНИК -lИМЯ_БИБЛИОТЕКИ -o РЕЗУЛЬТИРУЮЩИЙ_БИНАРИК

В нашем случае: gcc Dprogram1.c -L/home/amv/c/libs/ -ldynamic

(используйте g++ для программы на C++)

Запустим на исполнение полученный файл:

./a.out

В итоге должно получится:

Hello world!

I'm function hello()

Return code: 0

Связывание с библиотекой во время исполнения программы (C/C++):

Бывает необходимо подключать библиотеку во время выполнения программы. Для этого можно использовать функционал из заголовочного файла.

Исходный код примера (C):

#include <stdio.h>

#include < dlfcn.h >

int main()

{

void *handle = dlopen("libdynamic.so",RTLD_LAZY);

int(*fun)(void) = dlsym(handle,"hello");

int x = (*fun)();

dlclose(handle);

printf("Return code: %dn",x);

return 0;

};

Сохраните его в файле Dprogram2.c

В dlfcn.h определены следующие функции:

void* dlopen("PATH_AND_NAME",FLAG) - загружает в память динамическую библиотеку с полным именем PATH_AND_NAME и возвращает ее описатель (HANDLE) (NULL в случае неудачи). FLAG - флаги, описанные в "man dlopen";

void* dlsym(HANDLE,"NAME") - возвращает указатель на функцию/переменную, импортируемую из библиотеки;

int dlclose(HANDLE) - выгружает библиотеку из памяти;

const char *dlerror() - получить сообщение о последней возникшей ошибке (NULL - если ошибок не произошло с момента последнего вызова dlerror).

Выполняем:

gcc -ldl Dprogram2.c

(используйте g++ для программы на C++)

Запустим на исполнение полученный файл:

./a.out

В итоге должно получиться:

Hello world!

I'm function hello()

Return code: 0

* Важно! Нет необходимости помещать библиотеку в один из специальных каталогов, модифицировать переменные окружения и выполнять "ldconfig"

Соседние файлы в папке 5 семестр