C++[[gnu:: visibility("default")]] vs__declspec(dllexport) en Windows y Linux
attributes (1)
Necesitaba crear algunas bibliotecas compartidas en C ++ y utilicé Linux como mi sistema operativo desarrollador. Sé que necesito hacer visibles los símbolos si quiero cargarlos a través de dlsym
/ LoadLibrary
. Entonces, en Linux, todos mis símbolos siguieron este patrón:
extern "C" [[gnu::visibility("default")]] void f();
Utilicé clang con C ++ 11 habilitado y pude cargar f
en mi programa de host. Cuando me mudé a Windows utilicé GCC 4.8.2 con C ++ 11 activado y ese patrón también funcionó en Windows Machine con LoadLibrary
. (Necesitaba usar C ++ 11 para la nueva sintaxis de atributo). Sé que en Windows necesito usar __declspec(dllexport)
para exportar símbolos de la biblioteca compartida. ¿Y ahora qué? ¿ __declspec(dllexport)
no se requiere __declspec(dllexport)
?
Editar:
Encontré aquí que esos son sinónimos (creo) así que la pregunta es ¿existe un [[gnu::attribute]]
para __declspec(dllimport)
para evitar el uso de macros y ifdef
s para objetivos específicos?
La visibilidad del símbolo es sutilmente diferente de dllexport
, y la razón principal es que cuando compila un .dll
en Windows bajo mingw
/ cygwin
, el comportamiento predeterminado del vinculador es la opción -export-all-symbols
- es decir, exportará automáticamente todo de su .dll
por defecto.
Puede cambiar este comportamiento utilizando un archivo .def
o colocando __declspec((dllexport))
o __attribute((dllexport))
en cualquier rutina (es decir, si especifica que un único símbolo se va a exportar, solo los símbolos que están declarado exportado se exporta). Esto puede tener una mejora significativa del rendimiento en el tiempo de carga dll si hay muchos símbolos en su biblioteca.
Si desea usar el atributo C++
equivalente, entonces usa [[gnu::dllexport]]
Entonces, sí, use dllexport
para evitar que su .dll
exporte el mundo.
De manera similar, puede usar [[gnu:dllimport]]
para importar rutinas externas.
Cuidado al leer la documentación; lo que realmente dice es que cuando usas el atributo dllexport
, también activa la visibility:default
comportamiento visibility:default
menos que se anule.