Windows & C ++: extern & __declspec (dllimport) - PullRequest
       31

Windows & C ++: extern & __declspec (dllimport)

20 голосов
/ 18 февраля 2010

В чем разница / взаимосвязь между "extern" и "__declspec (dllimport")? Я обнаружил, что иногда необходимо использовать оба из них, иногда достаточно одного.

Прав ли я, что:

  1. "extern" для статически связанных библиотек,
  2. «__declspec (dllimport)» для DLL (динамически связанных библиотек),
  3. оба выполняют одну и ту же работу для соответствующего типа связи,
  4. вам нужно использовать оба, когда вы используете библиотеки импорта (небольшие .lib файлы, которые помогают связывать с dll)?

1 Ответ

32 голосов
/ 18 февраля 2010

extern означает, что объект имеет внешнюю связь, то есть виден за пределами своей единицы перевода (файл C или CPP). Это означает, что соответствующий символ будет помещен в объектный файл, и, следовательно, он также будет виден, если этот объектный файл станет частью статической библиотеки. Однако extern само по себе не означает, что символ также будет виден, как только объектный файл станет частью DLL.

__declspec(dllexport) означает, что символ должен быть экспортирован из DLL (если он действительно является частью DLL). Он используется при компиляции кода, который входит в DLL.

__declspec(dllimport) означает, что символ будет импортирован из DLL. Он используется при компиляции кода, который использует DLL.

Поскольку один и тот же заголовочный файл обычно используется как при компиляции самой DLL, так и в клиентском коде, который будет использовать DLL, обычно определяют макрос, который разрешается в __declspec(dllexport) при компиляции DLL и __declspec(dllimport) при компиляции его клиента, вот так:

#if COMPILING_THE_DLL
    #define DLLEXTERN __declspec(dllexport)
#else
    #define DLLEXTERN __declspec(dllimport)
#endif

Чтобы ответить на ваши конкретные вопросы:

  1. Да, extern достаточно для статических библиотек.
  2. Да - и декларации также требуется extern ( см. Объяснение здесь ).
  3. Не совсем - см. Выше.
  4. Вам не нужно строго extern с __declspec(dllimport) (см. Объяснение, связанное с выше), но, поскольку вы обычно будете использовать тот же заголовочный файл, у вас уже будет extern потому что это необходимо при компиляции DLL.
...