Скажімо, у вас є клас, Unusefulвизначений таким чином:
Файл Unuseful.h:
class Unuseful {
public:
void printUnusefulStatement();
};
Файл Unuseful.cpp:
#include "unuseful.h"
#include <iostream>
void Unuseful::printUnusefulStatement()
{
std::cout << "Hello world!" << std::endl;
}
Тепер у вас є інший клас, який потребує друку некорисних виписок:
Unuseful u;
u.printUnusefulStatement();
Це означає, що ви хочете використовувати зовнішню бібліотеку, що містить конкретну реалізацію ( printUnusefulStatement), яку ви хочете включити у свій код.
Ви можете використовувати цю бібліотеку двома способами:
- Надаючи компілятору вихідний код
- Надавши двійковий файл (який раніше був скомпільований для вашої архітектури), компонувальнику
Випадок 1: використання бібліотеки під час компіляції
Це найпростіший випадок. У вас є вихідний код бібліотеки, яким ви повинні скористатися, і вам просто потрібно скомпілювати його разом із наявним кодом (скажімо, main.cppфайлом). Зазвичай ви є автором і користувачем бібліотеки (класу, який виконує потрібне вам завдання).
Компіляція за допомогою цієї команди:
g++ main.cpp unuseful.cpp
дозволяє використовувати необхідну реалізацію у вашому main.cppфайлі.
Випадок 2: зв’язок бібліотеки
Частіше, ніж у випадку 1 , у вас немає вихідного коду бібліотеки, яку ви хочете використовувати. У вас є лише файл заголовка ( Unuseful.h, щоб продовжити приклад) і статична або спільна бібліотека (можливо, [*] libunuseful.aта libunuseful.soфайли відповідно).
Статична бібліотека - це архів об’єктних файлів ( *.o), які зв’язані всередині кінцевих виконуваних файлів, а спільні бібліотеки натомість завантажуються динамічно - під час виконання (дивіться на цій сторінці для кращого розуміння різниці ).
Статичні бібліотеки створюються простим архівуванням *.oфайлів за допомогою arпрограми:
# Create the object files (only one here)
g++ -c unuseful.cpp
# Create the archive (insert the lib prefix)
ar rcs libunuseful.a unuseful.o
Спільні бібліотеки створюються з g++ -sharedопцією:
# Create the object file with Position Independent Code[**]
g++ -fPIC -c unuseful.cpp
# Crate the shared library (insert the lib prefix)
g++ -shared -o libunuseful.so unuseful.o
Припустимо, тепер у вас є Unuseful.hфайл і спільна бібліотека ( libunuseful.soфайл), і у вас є main.cppфайл, який створює екземпляр Unusefulоб’єкта і викликає printUnusefulStatementметод.
Якщо ви спробуєте скомпілювати цей файл ( g++ main.cpp), компонувальник скаржиться, оскільки не може знайти printUnusefulStatementсимвол.
Пора користуватися бібліотекою:
g++ main.cpp -L. -lunuseful
-LОпція повідомляє компоновщик , де шукати бібліотеки файлів і -lпрапор вказує компоновщик ім'я бібліотеки , які будуть використовуватися (безlib префікса).
Тепер виконуваний файл ( a.outтому що я не вказав інше ім'я) створений, і ви використали бібліотеку для реалізації потрібної вам функціональності ( printUnusefulStatement).
Оскільки спільна бібліотека завантажується під час виконання, виконання a.outвиконуваного файлу може бути невдалим, оскільки система не може знайти бібліотеку. Зазвичай це може бути вирішено шляхом відповідного встановлення змінної середовища, що вказує, які шляхи використовувати для пошуку динамічних бібліотек:
# Set the LD_LIBRARY_PATH [*]
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
Готово, тепер ваш виконуваний файл скомпільовано, і він зможе запустити та завантажити потрібну йому бібліотеку.
Висновок
Це швидкий огляд бібліотек, який, я сподіваюся, може допомогти вам зрозуміти, як вони використовуються та надаються іншим.
Є багато багатьох аспектів, які слід дослідити більш докладно, якщо вас це цікавить: g++параметри під час створення спільних бібліотек, arпараметри, змінні середовища, формат спільних бібліотек тощо.
[*]: У середовищі Unix
" Цей параметр має значення для m68k, PowerPC та SPARC. Незалежний від позиції код вимагає спеціальної підтримки, тому працює лише на певних машинах. [Зі сторінки довідки g ++]
std::cout << "Hello World";ви користуєтесь бібліотекою. Чи можете ви бути більш конкретними?