Что на самом деле означает __declspec(dllimport)?

Я видел исходный код Qt так:

class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};

Который Q_CORE_EXPORT макрос определяет как показано ниже:

define Q_DECL_IMPORT __declspec(dllimport)

Так что же __declspec(dllimport) на самом деле означает?

3 ответа

Решение

__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(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 /questions/40159920/pochemu-kogda-declspec-dllimport-ne-nuzhen/40159934#40159934

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

Другие вопросы по тегам