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 поведение, если оно не отменено.

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