Питання, з яким ви пов’язали, посилається на функцію "Пов’язати бінарне з бібліотеками", яка дещо відрізняється від вбудованого двійкового файла.
"Пов’язати бінарне з бібліотеками" означає те, що ви очікуєте від нього щодо зв'язку: Незалежно від того, чи є бінарна статична бібліотека, динамічна бібліотека чи рамка, вона буде пов’язана з вашим об'єктним кодом у час посилання після компіляції.
Коли ви думаєте про зв'язок зі статичною бібліотекою, те, що відбувається, досить зрозуміло: лінкер копіює код з бібліотеки (наприклад libFoo.a
) у свій вихідний бінарний файл. Ваш вихідний файл збільшується в розмірі, але не потребує усунення зовнішніх залежностей під час виконання. Все, що потрібно виконати вашій програмі (стосовно статичної бібліотеки), з’являється після її побудови.
За допомогою динамічної бібліотеки (.dylib або системи, що постачається системою) очікується, що бібліотека, до якої ви пов'язуєтесь, буде присутня десь у шляху завантаження динамічної бібліотеки системи під час запуску програми. Таким чином, у вас немає накладних витрат на копіювання всіх сторонніх бібліотек у вашу двійкову систему, і всі різні програми на комп'ютері, які також посилаються на цю бібліотеку, зможуть її знайти, що заощадить мінімально місця на диску, але також потенційно простору пам'яті, залежно від того, як і де система кешує бібліотеки.
Рамка схожа на динамічну бібліотеку, але може містити ресурси в її структурі каталогів (зображення, аудіо, інші рамки тощо). У цьому випадку проста статична бібліотека або .dylib файл не вирізатимуть її, тому вам, можливо, доведеться зв’язатись із рамкою, щоб вона змогла знайти те, що потрібно для належного виконання.
Коли ви посилаєтесь на сторонні рамки (скажіть щось, що ви завантажили з github і створили самі), воно може бути відсутнім у системі, в якій ви маєте намір працювати. У цьому випадку ви не тільки посилаєтесь на рамку, але вбудовуєте її всередину пакету додатків, використовуючи фазу "Копіювати рамки". Коли ваша програма запускається, програма-лінкер виконання (він же розв’язувач) загляне всередину вашого пакета на додаток до шляху завантаження системи, знайде вбудований фреймворк і зв’яже його, щоб ваш додаток отримав код, який йому потрібен для запуску.
Нарешті, те, що є належним чином "вбудованим двійковим кодом" - це виконуваний файл, який ви обидва вбудовуєте у свій пакет додатків через фазу "Копіювати файли", і ви виконуєте самостійно, можливо, з викликом до popen()
або подібного. Ваша програма може викликати вбудований бінарний файл, але він не пов'язаний з ним. Це повністю зовнішня сутність (як програми в /bin
каталозі).
На практиці для системних бібліотек і фреймворків ви пов'язуєте їх, і це все, що вам потрібно зробити.
Якщо вам потрібно зв’язати створену бібліотеку, яка не потребує вбудованих ресурсів (тобто не вимагає існування рамки), то ви можете просто зв’язатись зі статичною бібліотекою. Якщо у вашій програмі є кілька модулів, які хочуть використовувати один і той самий код бібліотеки, перетворення його в рамки або динамічну бібліотеку і посилання на це можуть заощадити місце і може бути зручним (особливо, якщо використання пам'яті викликає занепокоєння).
Нарешті, рамки можуть включати не лише ресурси, але файли заголовків та / або ліцензій. Використання рамки для передачі цих файлів насправді є зручним механізмом розповсюдження, тому часто вам може знадобитися включити рамку, щоб ці речі могли позначати разом із вашим бінарним (тобто ліцензійні вимоги можуть зробити це обов’язковим).
--- редагувати ---
Адам Джонс написав таке коментар як коментар:
Це чудова відповідь. Однак є щось, в чому я трохи розгублений. Що означає виконати двійковий файл самостійно? Ви маєте на увазі просто використання коду вбудованого фреймворку? Я знаю, ти згадав popen (), але ти кажеш, що моя програма викликає popen ()? Я не знаю, що це означає.
Я кажу, що вбудований двійковий файл - це лише інший файл ресурсу у вашому пакеті, як-от аудіо-файл чи зображення, хоча натомість файл є виконуваним інструментом командного рядка. popen()
Функція ( man popen
від вашого терміналу , щоб дізнатися більше про це) дозволяє виконувати довільні програми з іншої запущеної програми. system()
Функція є ще одним способом. Є й інші, і я наведу історичний приклад, який може зробити розуміння використання вбудованого двійкового файлу дещо зрозумілішим:
Як ви, напевно, знаєте, що при запуску програми на Mac OS X він запускається з ідентифікатором користувача поточного користувача. У більшості поширених установок це типовий користувач у admin
користувальницькому робочому столі , якому надається ідентифікатор користувача 501
.
У операційних системах на базі Unix тільки root
користувач (ідентифікатор користувача 0
) має повний доступ до всієї файлової системи. Іноді трапляється, що програма-інсталятор, запущена користувачем Desktop, потребує встановлення файлів у привілейованому каталозі (наприклад, драйвери). У цьому випадку прикладній програмі потрібно ескалацію своїх привілеїв root
користувачеві, щоб вона могла писати в цих обмежених каталогах.
Щоб полегшити це в операційних системах через OS X 10.7, Apple надала у своєму API служб авторизації функцію AuthorizationExecuteWithPrivileges () (це тепер застаріло, але все ще є корисним прикладом).
AuthorizationExecuteWithPrivileges()
взяв за аргумент шлях до інструменту командного рядка для виконання як root
. Інструмент командного рядка являв собою виконуваний скрипт оболонки або скомпільований двійковий файл, який ви написали для запуску логіки встановлення. Цей інструмент було встановлено всередині вашої програми, як і будь-який інший файл ресурсів.
Зателефонувавши, ОС встановив діалогове вікно авторизації із запитом пароля користувача (ви вже бачили це раніше!), І коли він буде введений, буде виконано програму, як root
від вашого імені. Цей процес схожий лише на те, щоб виконати програму з popen()
собою, хоча popen()
поодинці не приносить користі ескалація привілеїв.