Статические и динамические библиотеки

Предыдущая тема Следующая тема Перейти вниз

Статические и динамические библиотеки

Сообщение  tux в Ср Окт 08, 2008 9:10 pm

С появлением многозадачных операционных систем (а может быть и раньше) возинкла потребность использовать один и тот же код в разных программах. Как вариант можно было включать исходник с необходимыми функциями в каждую программу, но от этого необходимы были затраты на оперативную память, да и размер самой программы тоже разростался. Тогда было решено делать бинарный код, наподобе самих программ, но в отличии от них имел несколько точек входа, и при этом не мог самостоятельно запускаться на выполнение. Назвали все это динамическими библиотеками, тк они хранили уже откомпилированные функции, которые можно было использовать в нескольких программах одновременно.
Иногда все же требовалось использовать откомпилированный кусок программы именно в самом исполняемом файле (обычно для уменьшения времени компиляции, или когда не хотели передавать код программы в открытом виде). Такие библиотеки получили название статических.
Сейчас же практически все операционные системы используют библиотеки. Так же в библиотеках распространяются множество серьезных программных продуктов, позволяющих программисту без особых проблем решать какие либо задачи (к примеру библиотеки графически и физических движков, библиотеки работы со звуком и пр.)

Динамические библиотеки

В операционной системе Windows эти библиотеки имеют расширение *.dll, в Linux *.so, однако это необязательно, но рекомендуемо.
Создание динамической библиотеки в FreeBASIC-е не представляется ничего сложного. Рассмотрим на примере:
Код:
declare function fSumma alias "fSumma" (byval pX as integer, byval pY as integer) as integer

function fSumma(byval pX as integer, byval pY as integer) as integer export
    function=pX+pY
end function
Создадим к примеру функцию для подсчета суммы двух операндов, возвращающей результат этой суммы.
Единственное что бросается в глаза, так это ключевое слово export, которое указывает, что эта функция может быть использована вне программы (точнее вне библиотеки), при этом никто не запрещает использовать ее и в самой библиотеки другими функциями.
Желательно все экспортируемые функции декларировать с ключевым словом alias, тк FreeBASIC при экспорте функции преобразует все названия функций в верхний регистр, и это может запутать, ля этого лучше явно указать под каким именем надо ее экспортировать, и избавиться от лишней головной боли.
В остальном все остается также как и обычных функций.
Ну а теперь откомпилируем нашу библиотеку именно как библиотеку, для этого надо указать соответствующий ключ при компиляции (у меня исходный код в файле mylib.bas):
Код:
fbc -dll mylib.bas
В результате получим файл mylib.dll, который и является нашей библиотекой (в Linux-е получим файл libmylib.so, но при этом всеравно используется ключ -dll).
Как видите здесь нет ничего сложного.

Подключение динамической библиотеки


Ну а теперь попробуем использовать нашу библиотеку в своей программе. Прежде чем подключать библиотеку, надо отметить, что существует два способа это сделать.
Первый способ заключается в том, что библиотеки подключаются при загрузке программы, и сразу загружаются.
Преимущетво такого способа заключается в том, что можно быть уверенным, что загрузку библиотеки за вас выполнит операционная система, и если вдруг произойдет какая либо ошибка, то она вам сообщит о ней.
Недостаток - необходимо четко знать название всех функций библиотеки и самой библиотеки, если будет какое либо несоответствие, то программа вообще не запустится. Также из недостатков можно отметить то, что требуется оперативной памяти, необходимой для загрузки всех библиотек сразу.
Второй способ, это подключать библиотеки во время выполнения программы.
Преимущесто этого метода заключается в том, что нет необходимости точно знать название библиотеки, те можно его узнать во время выполнения программы, или дать возможность пользователю выбрать его. С помощью этого метода реализуется технология так называемых "плагинов".
При реализации этого метода необходимо "вручную" выполнять загрузку и выгрузку библиотек, что представляет некие трудности, но и при этом гибкость, позволяя программисту оперировать с библиотеками по своему усмотрению.
Ну а теперь от теории к практике. Напишем программку вида:
Код:
declare function fSumm lib "mylib.dll" alias "fSumm" (byval pX as integer, byval pY as integer) as integer
print fSumm(3, 5)
sleep
Если все сделано было правильно, то в результате выведется результат работы функции.
В первой строчке декларируем нашу функцию. В принципе все также как и в декларации обычных функций за исключением ключевого слова lib после которого указывается название библиотеки, и слова alias о которой было сказано выше. Хоть alias и не является обязательным, если используется то же название функции, всеже использовать его рекомендуется во избежании проблем.
А теперь попробуем динамически подключить нашу библиотекую. Для этого используются функции DyLibLoad - для загрузки библиотеки в память, DyLibFree - для выгрузки библиотеки, DyLibSymbol - для получения указателя на функцию библиотеки.
Рассмотрим на примере:
Код:
dim ppMyLib as any ptr
dim fSumma as function (byval pX as integer, byval pY as integer) as integer
ppMyLib=dylibload("mylib.dll")
if ppMyLib=0 then
    print "Ошибка: не найдена библиотека"
    sleep
    end 1
end if
fSumma=dylibsymbol(ppMyLib, "fSumma")
if fSumma=0 then
    print "Ошибка: не найдена функция в библиотеке"
    sleep
    end 1
end if
print fSumma(3, 5)
dylibfree ppMyLib
sleep
А теперь подробно:
Код:
dim ppMyLib as any ptr
Создаем переменную, которая будет хранить указатель на нашу библиотеку.
Код:
dim fSumma as function (byval pX as integer, byval pY as integer) as integer
Может показаться странной запись, однако она как нельзя элегантно описывает весть смысл. Мы создаем переменную, которая являеся функцией. Для того чтобы эта функция работала, достаточно ей присвоить адрес реальной функции.
Код:
ppMyLib=dylibload("mylib.dll")
if ppMyLib=0 then
    print "Ошибка: не найдена библиотека"
    sleep
    end 1
end if
Получаем указатель на нашу библиотеку, одновременно подгружая ее в память, используя функцию dylibload. Замечу, что в отличие от первого способа, где название библиотеки было константным, то тут оно может хранится в переменной.
Код:
fSumma=dylibsymbol(ppMyLib, "fSumma")
if fSumma=0 then
    print "Ошибка: не найдена функция в библиотеке"
    sleep
    end 1
end if
Получаем с помощью функции dylibsymbol адрес нашей библиотечной функции. В качестве параметров передаем указатель на нашу загруженную библиотеку и название нашей функции.
теперь мы можем использовать нашу функцию в своей программе:
Код:
print fSumma(3, 5)
После того, как нам библиотека не нужна, ее можно выгрузить из памяти:
Код:
dylibfree ppMyLib

Статические библиотеки

Статические библиотеки в отличие от динамических "вкомпилирываются" в код самой программы.
Создание исходного кода статической библиотеки ничем не отличается от предыдущего примера, поэтому им и воспользуемся.
Статические библиотеки в Windows имеют расширение *.lib, в linux *.a.
Для создания статической библиотеки используется ключ компилятора -lib
Код:
fbc -lib mylib.bas
В результате получаем файл mylib.lib.
Подключать статическую библиотеку можно только одним способом, который рассмотрим на примере:
Код:
#inclib "mylib"
declare function fSumma alias "fSumma" (byval pX as integer, byval pY as integer) as integer
print fSumma(3, 5)
sleep
И все. Неправда ли удобно, все остальное сделает за нас компилятор.

Совмесное использование статических и динамических библиотек

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


Последний раз редактировалось: tux (Ср Май 20, 2009 7:28 pm), всего редактировалось 1 раз(а)
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Статические и динамические библиотеки

Сообщение  tux в Ср Окт 08, 2008 9:13 pm

Народ, будте добры, у кого будет время, проверьте исходники, просто ща под рукой винды нет, все из Линуха писал
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Статические и динамические библиотеки

Сообщение  Gena в Ср Ноя 05, 2008 9:28 pm

Не подскажите, как узнать доступные функции? - ведь без этого никак.

Gena

Сообщения : 182
Дата регистрации : 2008-11-05
Возраст : 23
Откуда : Москва

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Статические и динамические библиотеки

Сообщение  tux в Ср Ноя 05, 2008 9:37 pm

эээ, ну вообще, по хорошему, с библиотеками, которые предоставляются разработчикам, оставляют заголовочные файлы, в которых все эти функции и описаны, а из чужой библиотеки мона узнать тока названия функций и размер параметров (допустим если просмотреть библиотеку в шестнадцатеричном редакторе), сами параметры функций из откомпилированной библиотеки узнать невозможно, хотя если методом тыка...))
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Статические и динамические библиотеки

Сообщение  Eric-S в Пт Ноя 07, 2008 1:11 am

Хочу написать одну очень неприятную вещь. Меня, лично, она всегда бесила. Но против правды не попрёшь.
Нужно тыркаться в тыртырнете. Инет этоже такая свалка всего!
А если влом искать, то хоть уточните, что за dll. Может быть мы знаем и подскажем.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Статические и динамические библиотеки

Сообщение  vbman в Вс Дек 07, 2008 4:20 pm

Gena пишет:Не подскажите, как узнать доступные функции? - ведь без этого никак.

Откройте ДЛЛ в блокноте и ближе к концу файла там открытым текстом будут прописаны все экспортируемые функции.
avatar
vbman

Сообщения : 52
Дата регистрации : 2008-11-19
Возраст : 35
Откуда : Украина, Кировоград

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Статические и динамические библиотеки

Сообщение  tux в Вс Дек 07, 2008 5:50 pm

тока толку от них нет никакого, если незнаеш какие параметры необходимо передавать етим функциям...
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Статические и динамические библиотеки

Сообщение  Apokalipsis в Пн Авг 09, 2010 8:44 pm

В каком-нибудь хекс-редакторе можно просмотреть имена функций, но от этого толку никакого.
Я сейчас перешел на Purebasic, в нем есть две функции: GetLibraryFunctionName и GetLibraryfunctionParameter, вот с помощью них можно узнать все о DLL.
Кстати, даже где-то встречал уже исходник прожки, которая из либы вытаскивает все имена функций с количеством параметров и их входными данными, себе не скачал этот исходник, так как у меня последняя версия компилятора, и в нем сильно поменялся синтаксис, а править код влом.
Если будет интересно, поищу еще раз.

Apokalipsis

Сообщения : 5
Дата регистрации : 2009-11-28
Возраст : 30
Откуда : Донецк, Украина

Посмотреть профиль http://www.yuberion.se-symbian.ru

Вернуться к началу Перейти вниз

Re: Статические и динамические библиотеки

Сообщение  gromov в Чт Окт 14, 2010 10:16 pm

Маленькое дополнение
Использовать динамическое подключение библиотеки надо с осторожностью, так как компилятор на этапе компиляции не может проверить количество и правильность передаваемых в функцию библиотеки параметров. Хуже всего то, что ошибка может проявится не сразу - для некоторых значений функция библиотеки будет возвращать правильный результат, а для некоторых ...

Использование даного способа подключения оправдано в программах с модулями расширения (модулями работы с оборудованием) когда есть несколько библиотек с одинаковым интерфейсом. На етапе выполнения программа решит конкретно какой библиотекой пользоватся и вызвет необходимые функции. На этом принципе построена работа Total Commander с плагинами.

gromov

Сообщения : 7
Дата регистрации : 2008-08-31
Возраст : 39
Откуда : Украина, Броды

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Статические и динамические библиотеки

Сообщение  Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения