Как создать файл с расширением lib

Обновлено: 06.07.2024

Центр Аяза Шабутдинова / секреты и факты - YouTube YouTube. YouTube. О сервисе Прессе Авторские права Связаться с нами Авторам Рекламодателям Разработчикам Условия использования Конфиденциальность Правила и безопасность Как работает YouTube Тестирование новых функций.

Programm.ws - это сайт, на котором вы можете почитать литературу по языкам программирования , а так-же посмотреть примеры работающих программ на С++, ассемблере, паскале и много другого..

Программирование — в обычном понимании, это процесс создания компьютерных программ.
В узком смысле (так называемое кодирование) под программированием понимается написание инструкций — программ — на конкретном языке программирования (часто по уже имеющемуся алгоритму — плану, методу решения поставленной задачи). Соответственно, люди, которые этим занимаются, называются программистами (на профессиональном жаргоне — кодерами), а те, кто разрабатывает алгоритмы — алгоритмистами, специалистами предметной области, математиками.
В более широком смысле под программированием понимают весь спектр деятельности, связанный с созданием и поддержанием в рабочем состоянии программ — программного обеспечения ЭВМ. Более точен современный термин — «программная инженерия» (также иначе «инженерия ПО»). Сюда входят анализ и постановка задачи, проектирование программы, построение алгоритмов, разработка структур данных, написание текстов программ, отладка и тестирование программы (испытания программы), документирование, настройка (конфигурирование), доработка и сопровождение.

Глава 3. Процедуры в программах ассемблера

Как указать приложению местонахождение внешних функций, расположенных в DLL-библиотеках? Если бы приложение использовало только одну DLL-библиотеку, то проблем бы не было — указывай нужную и продолжай процесс сборки приложения. Если количество необходимых приложению DLL-библиотек больше одной, а тем более если их десятки, то ситуация требует иного решения, нежели простое перечисление нужных приложению DLL-библиотек. Для централизованного хранения информации о размещении используемых приложением функций в DLL-библиотеках применяют LIB-файлы. Эти файлы представляют собой своеобразный справочник о размещении функций в DLL-библиотеках. При этом не указывается никаких путей, так как при обращении к DLL-библиотеке операционная система ищет ее по следующему алгоритму.

Как создать корректную статическую (lib) библиотеку под MS-DOS (16 bit) из Windos (32-64 bit) или из MS-DOS?
Привет всем! Кто подскажет, как корректно создавать статические библиотеки для 16-битного режима.

Как в VS 2015 устранить ошибку LNK 1104 cannot open file 'fltkd.lib wsock32.lib comct132.lib fltkjpegd.lib'?
как устранить ошибку LNK 1104 в visual studio community 2015? пункта C/C++ в properties нету .

Как прикрепить *.lib файл в с++?
как прикрепить *.lib файл в с++? У меня есть *.lib (libdc_client.lib) файл и и *.h (dc_win32.h).


Как и возможно ли создать lib и h из dll?
Есть библиотека dll и больше ничего. Смогу ли я как-то сделать *.h и *.lib для того что бы.

  • имеется процедура для вывода шестнадцатеричных чисел, как ее правильно оформить и залепить в библиотечный файл
из obj- и def-файлов создают lib и dll
\masm32\bin\Link /SECTION:.bss,S /DLL /DEF:mfile.def /SUBSYSTEM:WINDOWS /LIBPATH:\masm32\lib mfile.obj . После компиляции получаем dll- и lib-файлы. Последний файл - это библиотека импорта, которую можно использовать, чтобы прилинковать к другим программам функции из соответствующего dll-файла. Для того чтобы работать с твоими функциями через вызов invoke понадобится еще и текстовый myfile.inc с описанием прототипов твоих функций
  • в коде используются команды 386го процессора, но в целом процедуры должны быть 16ти битными.
_______________________________________________
Win32 API. Урок 17. Динамические библиотеки

В этом туториале мы узнаем о dll, что это такое и как их создавать.
Вы можете скачать пример здесь.

Если вы програмиpуете достаточно долго, вы заметите, что программы, которые вы пишете, зачастую используют один и те же общие процедуры. Из-за того, что вам приходиться переписывать их снова и снова, вы теряете время. Во времена DOS'а программисты сохраняли эти общие процедуpы в одной или более библиотеках. Когда они хотели использовать эти функции, они всего лишь прилинковывали библиотеку к объектному файлу и линкер извлекал функции прямо из библиотек и вставлял их в финальный файл. Этот процесс называется статической линковкой. Хорошим примеpом являются стандартные библиотеки в C. У этого метода есть изъян - то, что в каждой программе у вас находятся абсолютно одинаковые копии функций. Впрочем, для ДОСовских программ это не очень большой недостаток, так как только одна программа могла быть активной в памяти, поэтому не происходила трата драгоценной памяти.

Под Windows ситуация стала более критичной, так как у вас может быть несколько прогpамм, выполняющихся одновременно. Память будет быстро пожираться, если ваша программа достаточно велика. У Windows есть решение этой проблемы: динамические библиотеки (dynamic link libraries). Динамическая библиотека - это что-то вpоде сборника общих функций. Windows не будет загружать несколько копий DLL в память; даже если одновременно выполняются несколько экземпляров вашей программы, будет только одна копия DLL в памяти. Здесь я должен остановиться и разъяснить чуть поподробнее. В реальности, у всех процессов, использующих одну и ту же dll есть своя копия этой библиотеки, однако Windows делает так, чтобы все процессы разделяли один и тот же код этой dll. Впрочем, секция данных копируется для каждого процесса.

Прогpамма линкуется к DLL во время выполнения в отличии от того, как это осуществлялось в старых статических библиотеках. Вы также можете выгрузить DLL во время выполнения, если она вам больше не нужна. Если программа одна использует эту DLL, тогда та будет выгружена немедленно. Hо если ее еще используют какие-то другие программы, DLL останется в памяти, пока ее не выгрузит последняя из использующих ее программ.

Как бы то ни было, пеpед линкером стоит сложная задача, когда он проводит фиксирование адресов в конечном исполняемом файле. Так как он не может "извлечь" функции и вставить их в финальный исполняемый файл, он должен каким-то обpазом сохранить достаточно информации о DLL и используемых функциях в выходном файле, чтобы тот смог найти и загрузить верную DLL во время выполнения.

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

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

Вы можете загрузить DLL самостоятельно, не полагаясь на Windows-загрузчик.

Следующий код является каркасом DLL.

Вышепpиведенная пpогpамма - это каpкас DLL. Каждая DLL должна иметь стаpтовую функцию. Windows вызывает эту функцию каждый pаз, когда: DLL загpужена в пеpвый pаз DLL выгpужена Создается тpед в том же пpоцессе Тpед pазpушен в том же пpоцессе

Вы можете назвать стаpтовую функцию как пожелаете, главное чтобы был END <имя_стаpтовой_функции>. Эта функция получает тpи паpаметpа, только пеpвые два из них важны.

hInstDLL - это хэндл модуля DLL. Это не тоже самое, что хэндл пpоцесса. Вам следует сохpанить это значение, так как оно понадобится вам позже. Вы не сможете ее получить в дальнейшем легко.

reason может иметь одно из следующих четыpех значений:

DLL_PROCESS_ATTACH DLL получает это значение, когда впервые загружается в адресное пространство процесса. Вы можете использовать эту возможность для того, чтобы осуществить инициализацию.
DLL_PROCESS_DETACK DLL получает это значение, когда выгружается из адресного пространства процесса. Вы можете использовать эту возможность для того, чтобы "почистить" за собой: освободить память и так далее.
DLL_THREAD_ATTACK DLL получает это значение, когда процесс создает новую ветвь.
DLL_THREAD_DETACK DLL получает это значение, когда ветвь в процессе уничтожена.
Вы возвращаете TRUE в eax, если вы хотите, чтобы DLL пpодолжала выполняться. Если вы возвратите FALSE, DLL не будет загружена. Например, если ваш инициализационный код должен зарезервировать память и он не может это сделать, стартовой функции следует возвратить FALSE, чтобы показать, что DLL не может запуститься.

Вы можете поместить ваши функции в DLL следом за стаpтовой функцией или до нее. Hо если вы хотите, чтобы их можно было вызвать из дpугих пpогpамм, вы должны поместить их имена в списке эксопоpтов в файле установок модуля.

DLL тpебуется данный файл на стадии pазpаботки. Мы сейчас посмотpим, что это такое.

Обычно у вас должна быть пеpвая стpока. Ключевое слово LIBRARY опpеделяет внутpеннее имя модуля DLL. Желательно, чтобы оно совпадало с именем файла.

EXPORTS говоpит линкеpу, какие функции в DLL экспоpтиpуются, то есть, могут вызываться из дpугих пpогpамм. В пpилагающемся пpимеpе нам нужно, чтобы дpугие модули могли вызывать TestFunction, поэтому мы указываем здесь ее имя.

Дpугое отличие заключается в паpаметpах, пеpедаваемых линкеpу. Вы должны указать /DLL и /DEF:<имя вашего def-файла>.

Паpаметpы ассемблеpа те же самые, обычно /c /coff /Cp. После компиляции вы получите .dll и .lib. Последний файл - это библиотека импоpта, котоpую вы можете использовать, чтобы пpилинковать к дpугим пpогpаммам функции из соответствующей .dll.

Далее я покажу вам как использовать LoadLibrary, чтобы загpузить DLL.

Как вы можете видеть, использование LoadLibrary чуть сложнее, но гоpаздо гибче.

Библиотеки позволяют использовать разработанный ранее программный код в различных программах. Таким образом, программист может не разрабатывать часть кода для своей программы, а воспользоваться тем, что входит в состав библиотек.

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

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

При компиляции программы библиотеки подключаются линковщиком, который вызывается gcc. Если программе требуются только стандартные библиотеки, то дополнительных параметров линковщику передавать не надо (есть исключения). Он "знает", где стандартные библиотеки находятся, и подключит их автоматически. Во всех остальных случаях при компиляции программы требуется указать имя библиотеки и ее местоположение.

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

Далее будет описан пример, в котором создается библиотека, после чего используется при создании программы.

Пример создания библиотеки

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

В итоге, когда все будет сделано, схема каталогов и файлов будет выглядеть так:

Пусть каталоги library и project находятся в одном общем каталоге, например, домашнем каталоге пользователя. Каталог library содержит каталог source с файлами исходных кодов библиотеки. Также в library будут находиться заголовочный файл (содержащий описания функций библиотеки), статическая (libmy1.a) и динамическая (libmy2.so) библиотеки. Каталог project будет содержать файлы исходных кодов проекта и заголовочный файл с описанием функций проекта. Также после компиляции с подключением библиотеки здесь будет располагаться исполняемый файл проекта.
В операционных системах GNU/Linux имена файлов библиотек должны иметь префикс "lib", статические библиотеки - расширение *.a, динамические - *.so.

Для компиляции проекта достаточно иметь только одну библиотеку: статическую или динамическую. В образовательных целях мы получим обе и сначала скомпилируем проект со статической библиотекой, потом — с динамической. Статическая и динамическая "разновидности" одной библиотеки по-идее должны называться одинаково (различаются только расширения). Поскольку у нас обе библиотеки будут находиться в одном каталоге, то чтобы быть уверенными, что при компиляции проекта мы используем ту, которую хотим, их названия различны (libmy1 и libmy2).

Исходный код библиотеки

В файле figure.c содержатся две функции — rect() и diagonals() . Первая принимает в качестве аргументов символ и два числа и "рисует" на экране с помощью указанного символа прямоугольник заданной ширины и высоты. Вторая функция выводит на экране две диагонали квадрата ("рисует" крестик).

В файле text.c определена единственная функция, принимающая указатель на символ строки. Функция выводит на экране звездочки в количестве, соответствующем длине указанной строки.

Заголовочный файл можно создать в каталоге source, но мы лучше сохраним его там, где будут библиотеки. В данном случае это на уровень выше (каталог library). Тем самым как бы подчеркивается, что файлы исходных кодов после создания из них библиотеки вообще не нужны пользователям библиотек, они нужны лишь разработчику библиотеки. А вот заголовочный файл библиотеки требуется для ее правильного использования.

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

Статическую библиотеку создать проще, поэтому начнем с нее. Она создается из обычных объектных файлов путем их архивации с помощью утилиты ar.

Все действия, которые описаны ниже выполняются в каталоге library (т.е. туда надо перейти командой cd). Просмотр содержимого каталога выполняется с помощью команды ls или ls -l.

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

В итоге в каталоге library должно наблюдаться следующее:

Далее используем утилиту ar для создания статической библиотеки:

Параметр r позволяет вставить файлы в архив, если архива нет, то он создается. Далее указывается имя архива, после чего перечисляются файлы, из которых архив создается.

Объектные файлы нам не нужны, поэтому их можно удалить:

В итоге содержимое каталога library должно выглядеть так:

, где libmy1.a — это статическая библиотека.

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

Объектные файлы для динамической библиотеки компилируются особым образом. Они должны содержать так называемый позиционно-независимый код (position independent code). Наличие такого кода позволяет библиотеке подключаться к программе, когда последняя загружается в память. Это связано с тем, что библиотека и программа не являются единой программой, а значит как угодно могут располагаться в памяти относительно друг друга. Компиляция объектных файлов для динамической библиотеки должна выполняться с опцией -fPIC компилятора gcc:

В отличие от статической библиотеки динамическую создают при помощи gcc указав опцию -shared:

Использованные объектные файлы можно удалить:

В итоге содержимое каталога library:

Использование библиотеки в программе

Исходный код программы

Теперь в каталоге project (который у нас находится на одном уровне файловой иерархии с library) создадим файлы проекта, который будет использовать созданную библиотеку. Поскольку сама программа будет состоять не из одного файла, то придется здесь также создать заголовочный файл.

Функция data() запрашивает у пользователя данные, помещая их в массив strs. Далее вызывает библиотечную функцию diagonals() , которая выводит на экране "крестик". После этого на каждой итерации цикла вызывается библиотечная функция text() , которой передается очередной элемент массива; функция text() выводит на экране звездочки в количестве равному длине переданной через указатель строки.

Обратите внимание на то, как подключается заголовочный файл библиотеки: через относительный адрес. Две точки обозначают переход в каталог на уровень выше, т.е. родительский по отношению к project, после чего путь продолжается во вложенный в родительский каталог library. Можно было бы указать абсолютный путь, например, "/home/pl/c/les22/library/mylib.h". Однако при перемещении каталогов библиотеки и программы на другой компьютер или в другой каталог адрес был бы уже не верным. В случае с относительным адресом требуется лишь сохранять расположение каталогов project и library относительно друг друга.

Здесь два раза вызывается библиотечная функция rect() и один раз функция data() из другого файла проекта. Чтобы сообщить функции main() прототип data() также подключается заголовочный файл проекта.

Файл project.h содержит всего одну строчку:

Из обоих файлов проекта с исходным кодом надо получить объектные файлы для объединения их потом с файлом библиотеки. Сначала мы получим исполняемый файл, содержащий статическую библиотеку, потом — связанный с динамической библиотекой. Однако с какой бы библиотекой мы не компоновали объектные файлы проекта, компилируются они как для статической, так и динамической библиотеки одинаково:

При этом не забудьте сделать каталог project текущим!

Компиляция проекта со статической библиотекой

Теперь в каталоге project есть два объектных файла: main.o и data.o. Их надо скомпилировать в исполняемый файл project, объединив со статической библиотекой libmy1.a. Делается это с помощью такой команды:

Начало команды должно быть понятно: опция -o указывает на то, что компилируется исполняемый файл project из объектных файлов.

Помимо объектных файлов проекта в компиляции участвует и библиотека. Об этом свидетельствует вторая часть команды: -L../library -lmy1. Здесь опция -L указывает на адрес каталога, где находится библиотека, он и следует сразу за ней. После опции -l записывается имя библиотеки, при этом префикс lib и суффикс (неважно .a или .so) усекаются. Обратите внимание, что после данных опций пробел не ставится.

Опцию -L можно не указывать, если библиотека располагается в стандартных для данной системы каталогах для библиотек. Например, в GNU/Linux это /lib/, /urs/lib/ и др.

Запустив исполняемый файл project и выполнив программу, мы увидим на экране примерно следующее:

Посмотрим размер файла project:

Его размер равен 8698 байт.

Компиляция проекта с динамической библиотекой

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

Здесь в отличии от команды компиляции со статической библиотеки добавлены опции для линковщика: -Wl,-rpath. /library/. -Wl - это обращение к линковщику, -rpath - опция линковщика, ../library/ - значение опции. Получается, что в команде мы два раза указываем местоположение библиотеки: один раз с опцией -L, а второй раз с опцией -rpath. Видимо для того, чтобы понять, почему так следует делать, потребуется более основательно изучить процесс компиляции и компоновки программ на языке C.

Следует заметить, что если вы скомпилируете программу, используя приведенную команду, то исполняемый файл будет запускаться из командной строки только в том случае, если текущий каталог project. Стоит сменить каталог, будет возникать ошибка из-за того, что динамическая библиотека не будет найдена. Но если скомпилировать программу так:

, т.е. указать для линковщика абсолютный адрес, то программа в данной системе будет запускаться из любого каталога.

Размер исполняемого файла проекта, связанного с динамической библиотекой, получился равным 8544 байта. Это немного меньше, чем при компиляции проекта со статической библиотекой. Если посмотреть на размеры библиотек:

, то видно, что динамическая больше статической, хотя исполняемый файл проекта со статической библиотекой больше. Это доказывает, что в исполняемом файле, связанном с динамической библиотекой, присутствует лишь ссылка на нее.


В своих программа, мы постоянно набираем одни и те же куски кода, например, - работа с Аналого – Цифровым Преобразователем, Приемо-Передатчиком и т.д. Чтобы не создавать постоянную «волокиту» с повторяющимся кодом, все это можно оформить в виде файлов библиотеки ( т.назыв. библитеки различного назначения ).

Создавать библиотечные файлы можно тремя способами:


• Связка файлов *.lib <-> *.h

null

• Связка файлов *.c <-> *.h


• Собственно файлом реализации *.c


Библиотечные файлы *.lib и *.h

В корневой папке CodeVisionAVR имеется каталог /lib, в котором находятся файлы с расширением *.lib ( например - LCD.LIB , DS1621.LIB и т.д. ), входящие в комплект поставки программы. Это Объектные файлы библиотеки ( Object File Library ). Они содержат определения функций – собственно реализацию.
В каталоге /inc находятся файлы с расширением *.h ( например - LCD.H , DS1621.H и т.д. ) входящие в комплект поставки программы. Это заголовочные файлы ( Header ); в них содержатся прототипы функций. Header файлы собственно и подключаются в основном проекте:

Заголовочный файл LCD.H

//прототипы функций
. . . .
void _lcd_write_data( unsigned char data );
. . . .
void lcd_putsf( char flash *str );
unsigned char lcd_init( unsigned char lcd_columns );


Объектный файл библиотеки LCD.LIB

Как видно, С-шная функция с ассемблерными вставки: используются всеми известные ассемблерные команды. С ними можно ознакомиться, посмотрев последние страницы PDF-документации на какой – либо микроконтроллер, например,- Atmega8535.

На основе выше указанных разъяснений, создадим свою библиотеку для примера.

В каталоге /lib создадим текстовый файл ( text file.txt ) и не отменяя переименование назовем его как function.lib . Запишем в него две функции и определение пользовательского типа:

//пользовательский тип
enum select< C,ASM >; //C - 0, ASM - 1

В каталоге /inc создадим текстовый файл ( text file.txt ) и не отменяя переименование назовем его как function.h . Запишем в него прототипы функций:

//прототипы функций
void light_On( unsigned char select );
void light_Off( unsigned char select );

Создадим проект в среде CodeVisionAVR без мастера кода( CodeWizardAVR ). Эти этапы были описаны в статье CodeVisionAVR. Первый проект для микроконтроллера AVR.
В главный файл проекта main.c записаваем код программы. Подключаем Header файл библиотеки:


Главная функция main :

void main( void )
light_On( C ); delay_ms( 500 );
light_Off( C ); delay_ms( 500 );

light_On( ASM ); delay_ms( 500 );
light_Off( ASM ); delay_ms( 500 );

Файлы проекта и библиотеки скачать можно здесь

Библиотечные файлы *.c и *.h

Это связка библиотечных файлов в языке С является общепринятой. *.h – заголовочный файл, который содержит прототипы функций. Header файл может также содержать любое разнообразие макросов, структур и всевозможных объявлений:


Файл с расширением *.C содержит определение функции т.е. её полную реализацию:

void port_init( void )
DDRD= 0x84 ;
PORTD= 0xEF ;
DDRC= 0x04 ;
PORTC= 0xf0 ;
>

void adc_init( void )
//Инициализация АЦП
ADMUX=MUX0; //ADC0
ADCSRA= 0xCE ;
SFIOR&= 0xEF ;
>

Удалим файл function.h от предыдущего варианта библиотеки. В каталоге /inc создадим два файла с расширением *.c и *.h .

В Header файле запишем код:

void lightSetup( unsigned char swt );
void lightFadeInOut( unsigned char value );

В Си файле реализации запишем код:

//пользовательский тип ON=0, OFF=1
enum select< ON,OFF >;

void lightSetup( unsigned char swt )
switch ( swt )
case ON: PORTD. 0 = 1 ; break ;
case OFF: PORTD. 0 = 0 ; break ;
>
>

void lightFadeInOut( unsigned char value )
PORTC=value;
>

Код программы в файле проекта main.c :

void main( void )
lightSetup( ON ); delay_ms( 500 );
lightSetup( OFF ); delay_ms( 500 );

Файлы проекта и библиотеки скачать можно здесь


Source файл реализации *.C

Создать библиотечный файл не применяя header - файлов, можно используя только файл реализации *.C . В нём прописываем необходимые определения переменных, структуры, прототипы функций и собственно их полную реализацию. На мой взгляд, это более простое решение в создании библиотечных файлов, и большинство программистов это используют( имеются знакомые программисты, которые так поступают! ).
Удалим файлы function.h и function.c от предыдущего варианта библиотеки и создадим source файл function.c , в который добавим код:

//прототипы функций
//предварительное объявление

void lightSetup( unsigned char swt );
void lightFadeInOut( unsigned char value );

//реализация функций ( определение )
//функции можно распологать и делать вызовы из других функций в любом порядке

void lightSetup( unsigned char swt )
switch ( swt )
case ON: PORTD. 0 = 1 ; break ;
case OFF: PORTD. 0 = 0 ; break ;
>
>

void lightFadeInOut( unsigned char value )
PORTC=value;
>

Код программы в файле проекта main.c :

void main( void )
lightSetup( ON ); delay_ms( 500 );
lightSetup( OFF ); delay_ms( 500 );

Читайте также: