C++ [[gnu::visibility("default")]] vs __declspec(dllexport) в Windows и Linux
Мне нужно было создать несколько общих библиотек на C++, и я использовал Linux в качестве операционной системы для разработчиков. Я знаю, что мне нужно сделать символы видимыми, если я хочу загрузить их через dlsym
/LoadLibrary
, Так что в Linux все мои символы следовали этой схеме:
extern "C" [[gnu::visibility("default")]] void f();
Я использовал clang с включенным C++11 и смог загрузить f
в моей принимающей программе. Когда я перешел на Windows, я использовал GCC 4.8.2 с включенным C++11, и этот шаблон работал на машине Windows также с LoadLibrary
, (Мне нужно было использовать C++11 для нового синтаксиса атрибутов). Я знаю, что на окнах мне нужно использовать __declspec(dllexport)
экспортировать символы из общей библиотеки. И что теперь? Является __declspec(dllexport)
не требуется больше?
Редактировать:
Я нашел здесь, что это синонимы (я думаю), поэтому вопрос в том, есть ли [[gnu::attribute]]
за __declspec(dllimport)
избегать использования макросов и ifdef
для конкретных целей?
1 ответ
Видимость символа слегка отличается от dllexport
- и основная причина в том, что когда вы компилируете .dll
в винде под mingw
/cygwin
поведение компоновщика по умолчанию - опция -export-all-symbols
- т.е. он будет автоматически экспортировать все из вашего .dll
по умолчанию.
Вы можете изменить это поведение, используя .def
файл или положить либо __declspec((dllexport))
или же __attribute((dllexport))
в любой подпрограмме (т. е. если вы указываете, что один символ должен быть экспортирован, то экспортируются только объявленные экспортированные символы). Это может значительно повысить производительность при загрузке DLL, если в вашей библиотеке много символов.
Если вы хотите использовать эквивалент C++
атрибут, то вы используете [[gnu::dllexport]]
Так что да, используйте dllexport
держать свой .dll
от экспорта мира.
Аналогичным образом вы можете использовать [[gnu:dllimport]]
для импорта внешних подпрограмм.
Внимательнее при чтении документации; что на самом деле говорит о том, что когда вы используете dllexport
атрибут, он также вызывает visibility:default
поведение, если оно не отменено.