Я бачив вихідний код Qt таким:
class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
Який Q_CORE_EXPORTмакрос визначає, як показано нижче:
define Q_DECL_IMPORT __declspec(dllimport)
То що __declspec(dllimport)насправді означає?
Я бачив вихідний код Qt таким:
class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
Який Q_CORE_EXPORTмакрос визначає, як показано нижче:
define Q_DECL_IMPORT __declspec(dllimport)
То що __declspec(dllimport)насправді означає?
Відповіді:
__declspec є специфічним атрибутом Microsoft, який дозволяє вказати інформацію про клас зберігання.
(Nitpicker's Corner: Однак низка інших постачальників компіляторів - наприклад, GCC - тепер підтримує це мовне розширення для сумісності з встановленою базою коду, написаного для компіляторів Microsoft. Деякі навіть надають додаткові атрибути класу сховища.)
Двома з тих атрибутів класу сховища, які можна вказати, є dllimportта dllexport. Вони вказують компілятору, що функція або об'єкт імпортується або експортується (відповідно) з DLL.
Більш конкретно, вони визначають інтерфейс DLL для клієнта, не вимагаючи визначення модуля (.DEF файлу ). Більшості людей набагато простіше використовувати ці розширення мови, ніж створювати файли DEF.
Зі зрозумілих причин __declspec(dllimport)і, __declspec(dllexport)як правило, поєднуються між собою. Ви використовуєте dllexportдля позначення символу як експортованого з DLL, і використовуєтеdllimport для експортування цього експортованого символу в інший файл.
Через це, і оскільки один і той же заголовочний файл зазвичай використовується як під час компіляції DLL, так і в клієнтському коді, який використовує інтерфейс DLL, загальним шаблоном є визначення макросу, який автоматично перетворюється на відповідний специфікатор атрибутів під час компіляції. Наприклад:
#if COMPILING_DLL
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
А потім позначення всіх символів, які слід експортувати DLLEXPORT.
Імовірно, саме це робить Q_CORE_EXPORTмакрос, вирішуючи або Q_DECL_IMPORTабо Q_DECL_EXPORT.
__declspecпозначення як розширення мови С ++. Я вважаю, що GCC зараз це підтримує, але це в першу чергу з міркувань сумісності з компіляторами Microsoft. І я не розумію, чим "MS-specific" відрізняється від "specific-compiler". Корпорація Майкрософт написала компілятор C ++, і багато людей використовують її. Він поставляється з Visual Studio.
__declspec(dllimport) це специфікатор класу сховища, який повідомляє компілятору, що функція або об'єкт або тип даних визначені у зовнішній бібліотеці DLL.
Функція або об'єкт або тип даних експортуються з DLL із відповідним __declspec(dllexport).
__declspec(dllexport)повідомляє компілятору повідомити лінкера про те, що ці символи потрібно розмістити в таблиці експорту (при компілюванні .dll). Під час компіляції програми, яка зв'язується з .dll, __declspec(dllimport)повідомляє компілятору, щоб він створив абсолютний абсолютний регістр-непрямий непрямий виклик (який компонувальник заповнить з роздільною здатністю, щоб вказати на таблицю імпорту), а не звичайний ріп-відносний регістр-прямийінструкція непрямого виклику до невизначеної функції (яка, оскільки не може змінити інструкцію, компоновщик вставляє відносну адресу транка, а потім створює транк, всередині якого розміщує відносний абсолютний регістр-непрямий непрямий виклик до покажчик функції в таблиці імпорту). Це оптимізація розміру та швидкості коду. Саме бібліотека імпорту .lib повідомляє компоновщику, які символи будуть імпортовані, і використовується як керівництво для створення таблиці імпорту та створення необхідних хитрощів у сегменті .text.
https://docs.microsoft.com/en-us/cpp/build/importing-function-calls-using-declspec-dllimport?view=vs-2019 https://docs.microsoft.com/en-us/cpp / build / importing-data-using-declspec-dllimport? view = vs-2019 https://stackoverflow.com/a/4490536/7194773
Це означає, що визначення функції знаходиться в динамічній бібліотеці. Докладнішу інформацію та приклади можна отримати в документації .