NO compartir todas las clases con la biblioteca compartida
-
08-07-2019 - |
Pregunta
Tan feo como el compilador win32 de Microsoft es utilizando la macro __declspec , tiene la ventaja de ser explícito sobre lo que desea exportar o no.
¡Mover el mismo código a un sistema Linux gnu / gcc ahora significa que todas las clases se exportan! (?)
¿Es esto realmente cierto?
¿Hay alguna manera de NO exportar una clase dentro de una biblioteca compartida bajo gcc?
#ifndef WIN32
#define __IMPEXP__
#else
#undef __IMPEXP__
#ifdef __BUILDING_PULSETRACKER__
#define __IMPEXP__ __declspec(dllexport)
#else
#define __IMPEXP__ __declspec(dllimport)
#endif // __BUILDING_PULSETRACKER__
#endif // _WIN32
class __IMPEXP__ MyClass
{
...
}
Solución
Esto es posible en GCC 4.0 y versiones posteriores. La gente de GCC considera esta visibilidad . Hay un buen artículo en el wiki de GCC sobre el tema. Aquí hay un fragmento de ese artículo:
#if defined _WIN32 || defined __CYGWIN__
#ifdef BUILDING_DLL
#ifdef __GNUC__
#define DLL_PUBLIC __attribute__((dllexport))
#else
#define DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax.
#endif
#else
#ifdef __GNUC__
#define DLL_PUBLIC __attribute__((dllimport))
#else
#define DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax.
#endif
#define DLL_LOCAL
#else
#if __GNUC__ >= 4
#define DLL_PUBLIC __attribute__ ((visibility("default")))
#define DLL_LOCAL __attribute__ ((visibility("hidden")))
#else
#define DLL_PUBLIC
#define DLL_LOCAL
#endif
#endif
extern "C" DLL_PUBLIC void function(int a);
class DLL_PUBLIC SomeClass
{
int c;
DLL_LOCAL void privateMethod(); // Only for use within this DSO
public:
Person(int _c) : c(_c) { }
static void foo(int a);
};
Otros consejos
Si una clase no debería estar disponible, no debería estar en un encabezado público. ¿Cuál es el punto de compartir declaraciones de cosas que el usuario no puede usar?