c++ - ¿Cómo puedo anular una anotación con clase__declspec(dllexport) en una base por miembro?
visual-c++ visibility (2)
Nunca hice tal cosa, sin embargo, siguiendo la documentación de MSDN debería ser posible.
No debe especificar ninguna __declspec
en el nivel de clase, y solo especifique __declspec(dllexport)
para los miembros que desee.
Espero que esto ayude.
En objetivos ELF, si tengo class Foo
y le he dado visibilidad default
través de una declaración como class __attribute__((visibiility("default"))) Foo
, entonces puedo eximir selectivamente a ciertos miembros de la clase de tener visibilidad default
anotando explícitamente con __attribute__((visibility("hidden"))
. Esto puede ser útil para métodos en línea que no deberían formar parte de ABI, de modo que si se emiten al construir la biblioteca que define la class Foo
, no se exportan, o para miembros private
o tipos dentro de la class Foo
que tampoco deberían formar parte de su ABI.
Sin embargo, en Windows, parece que no hay medios para lograr esto. Mientras que una class Foo
sin adornos class Foo
es automáticamente privada para una DLL, una vez adornada como class __declspec(dllexport) Foo
, toda la clase ahora es dllexport
, y parece que no hay ninguna anotación asociada que pueda anular selectivamente el estado __dllexport
de un miembro específico. Etiquetar los miembros seleccionados "no exportar" como __declspec(dllimport)
es claramente incorrecto.
¿Hay alguna otra forma de evitar que la clase __dllexport
ámbito de aplicación se aplique a ciertos miembros y / o tipos de clase?
Para hacer esto más concreto, lo que me gustaría decir, y puedo decir, cuando uso anotaciones ELF es:
class __attribute__((visibility("default"))) Foo {
public:
Foo(); // OK, default visibility
// Don''t let inlines join the ABI
__attribute__((visibility("hidden")) inline void something() { ... }
private:
// Don''t let private members join the ABI
__attribute__((visibility("hidden")) void _internal();
// Our pImpl type is also not part of the ABI.
struct __attribute__((visibility("hidden")) pimpl;
};
Pero no puedo formar lo mismo usando los atributos de MSVC:
class __declspec(dllexport) Foo {
public:
Foo(); // OK, dllexport''ed
// Don''t let inlines join the ABI, but how to say it?
__declspec(???) inline void something() { ... }
private:
// Don''t let private members join the ABI, but how?
__declspec(???) void _internal();
// Our pImpl type is also not part of the ABI, but how?
struct __declspec(???) pimpl;
};
En una implementación en el mundo real, espero que la variación entre estos se oculte detrás de una macro.
¿Hay algún __declspec
que estoy pasando por alto que tenga la semántica de __attribute__((visibility("hidden")))
y pueda anular la aplicación de ámbito de clase de __declspec(dllexport)
?
La documentación de MSDN da una idea de cómo se puede hacer. Aquí hay una muestra.
DLL_declspec.h:
#elif defined(BUILD_DLL)
#define DLL_DECLSPEC __declspec(dllexport)
#else
#define DLL_DECLSPEC __declspec(dllimport)
#endif
Para exportar toda la clase:
#include "DLL_declspec.h"
class DLL_DECLSPEC TestExport
{
public:
TestExport();
~TestExport();
std::string getName();
int getID();
};
Para exportar solo miembros seleccionados de la clase:
#include "DLL_declspec.h"
class TestExport
{
public:
DLL_DECLSPEC TestExport();
DLL_DECLSPEC ~TestExport();
DLL_DECLSPEC std::string getName();
int getID();
};