Мне нужно было создать несколько общих библиотек на 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
для конкретных целей?
Видимость символа слегка отличается от dllexport
— и основная причина в том, что когда вы компилируете .dll
в винде под mingw
/cygwin
, по умолчанию поведение компоновщика это вариант -export-all-symbols
— то есть это будет автоматический экспорт все от твоего .dll
по умолчанию.
Вы можете изменить это поведение, используя .def
файл или положить либо __declspec((dllexport))
или же __attribute((dllexport))
на любой подпрограмма (т.е. если вы указываете, что один символ должен быть экспортирован, то экспортируются только те символы, которые объявлены экспортированными). Это может значительно повысить производительность при загрузке DLL, если в вашей библиотеке много символов.
Если вы хотите использовать эквивалент C++
атрибут, то вы используете [[gnu::dllexport]]
Так что да, используйте dllexport
держать свой .dll
от экспорта мира.
Аналогичным образом вы можете использовать [[gnu:dllimport]]
для импорта внешних подпрограмм.
Внимательнее при чтении документации; что на самом деле говорит о том, что когда вы используете dllexport
атрибут, он также вызывает visibility:default
поведение, если оно не отменено.
Других решений пока нет …