Ne pas partager toutes les classes avec une bibliothèque partagée
-
08-07-2019 - |
Question
Aussi laid que soit le compilateur Microsoft Win32 en utilisant la macro __ declspec , il présente l’avantage d’être explicite sur ce que vous voulez exporter ou non.
Déplacer le même code sur un système Linux gnu / gcc signifie maintenant que toutes les classes sont exportées! (?)
Est-ce vraiment vrai?
Existe-t-il un moyen de NE PAS exporter une classe dans une bibliothèque partagée sous 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
{
...
}
La solution
Ceci est possible dans GCC 4.0 et versions ultérieures. Les membres de GCC considèrent cette visibilité . Il existe un bon article sur le wiki de GCC sur le sujet. Voici un extrait de cet article:
#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);
};
Autres conseils
Si une classe ne devrait pas être disponible, elle ne devrait pas figurer dans un en-tête public. Quel est l'intérêt de partager des déclarations d'objets que l'utilisateur ne peut pas utiliser?