Думаю, что с динамически подключаемыми библиотеками, или, как говорят в народе, с dll’ками (Dynamic-link library) знакомы все. Но не все знают, что без этих файлов использование компьютера превратилось бы в сущую пытку. Во-первых, размеры любого ехе-файла перевалили бы за сотню мегабайт, во-вторых, обновление софта свелось бы к переустановке всей программы с нуля, в-третьих, исчезли бы плагины в общем, полный хаос. Не зря на иконках этих файлов изображены две шестеренки. Без них не работала б любая машина, поэтому ни одна программа не может обойтись без DLL. Давайте рассмотрим, что же кроется за этими двумя шестеренками и подробнее ознакомимся с их работой.
В динамических библиотеках содержатся функции и классы, рассчитанные на экспорт в программу, которая обращается к данной библиотеке. В ОС Windows эти библиотеки могут содержать как экспортируемые, так и внутренние функции, недоступные для вызова «снаружи». Особенностью динамического подключения является то, что одну и ту же библиотеку одновременно могут «эксплуатировать» несколько программ одновременно. Благодаря этому программистам не надо заново писать стандартные или часто повторяемые функции достаточно сделать это один раз, создать DLL и подключать его по мере надобности. Этим сразу можно убить сразу трех зайцев: уменьшаются размеры ехе-файлов, упрощается процесс разработки нового софта и его обновления ведь достаточно будет только исправить функции в соответствующей библиотеке, а не перекомпилировать весь проект целиком. Ну и, конечно, всем известна такая штука как плагин. Большинство из них устанавливаются путем добавления новых dll-файлов в соответствующую директорию.
Думаю, теории на сегодня хватит, пора переходить к практике. Для начала создадим DLL и назовем его system.dll. В нем мы создадим две экспортируемые функции Hello() и NumberList(int a). Первая выведет на экран фразу Hello from system.dll, а вторая выведет 10 цифр с приростом +1 начиная с числа а. Ну что, поехали? Создайте новый dll-проект и запишите туда следующее:
Теперь объясню. После вставки стандартных библиотек ввода/вывода мы объявляем прототипы к нашим функциям. extern "C" указывает на то, что при вызове библиотеки будут использоваться команды языка С. __declspec(dllexport) используется для пометки данной функции (или класса) как экспортируемой. Далее идут сами функции. Внимание привлекает разве что строка GetModuleFileName(NULL,(LPTSTR)name,70). Предназначение этой функции записать полный путь ехе-файла, который вызвал данную библиотеку, в массив name.
После компиляции мы получим наш system.dll, а также system.lib и system.exp. Теперь напишем небольшую консольную программку, которая будет использовать нашу библиотеку (как вы уже, наверное, догадались, номера строк вводить не надо). Перед компиляцией не забудьте скопировать system.dll в папку с экзешником, или пропишите полный путь к библиотеке в 11-й строке.
В начале мы объявляем два типа указателя. Первый (pfunc1) это указатель на void-функцию, которая не принимает никаких параметров. Второй (pfunc2) то же самое, только на функцию с одним параметром типа int. Потом в строке 11 мы подгружаем нашу dll’ку и создаем переменную hLib для управления ею.
В случае ошибки мы увидим соответствующее сообщение. Если все прошло гладко, то программа сообщит об успешном подключении библиотеки . Далее мы связываем указатель One с функцией Hello(), и Two с функцией NumberList(int а). Если этого не произошло, то программа выведет сообщение об ошибке, «освободит» библиотеку и сложит все свои полномочия :-). В противном случае мы увидим результат работы обеих функций на экране. В конце программы нужно обязательно освободить используемую библиотеку, что мы и делаем. Вот и все.
Напоследок я хотел бы предупредить пользователей Borland C++ 5.02 и Borland C++ Builder. Дело в том, что эти компиляторы генерируют DLL не так, как MS Visual C++. Они добавляют символ подчеркивания к имени экспортируемой функции. Поэтому если вы пользуетесь компиляторами фирмы Borland, измените строки 20 и 21 следующим образом:
Ну вот и все. Конечно, создание библиотек дело тонкое, и рассказать про все сразу невозможно, но все начинается с самого простого. А дальше… было б только желание!