Как я могу переопределить аннотацию __declspec (dllexport) класса, предназначенную для каждого члена?
В целевых ELF, если у меня есть class Foo
, и я дал ему видимость default
с помощью объявления типа class __attribute__((visibiility("default"))) Foo
, тогда я могу выборочно освободить некоторых членов класса от видимости default
, явно аннотируя их с __attribute__((visibility("hidden"))
. Это может быть полезно для встроенных методов, которые не должны составлять часть ABI, поэтому, если они генерируются при создании библиотеки, определяющей class Foo
, они не экспортируются или для private
членов или типов внутри class Foo
, которые должны также не являются частью его ABI.
Однако, в Windows, похоже, нет средств для достижения этого. В то время как неприкрашенный class Foo
автоматически является приватным для DLL, однажды украшенный как class __declspec(dllexport) Foo
, весь класс теперь dllexport
, и, похоже, нет связанной аннотации, которая может выборочно переопределять статус __dllexport
определенного члена, Маркировка элементов "не для экспорта" как __declspec(dllimport)
явно неверна.
Есть ли другой способ предотвратить использование класса __dllexport
для определенных членов класса и/или типов?
Чтобы сделать это более конкретным, что я хотел бы сказать и могу сказать, при использовании аннотаций ELF:
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;
};
Но я не могу создать одно и то же, используя атрибуты 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;
};
В реализации реального мира я ожидаю, что разница между ними будет скрыта за макросом.
Есть ли какой-то __declspec
, который я пропускаю, который имеет семантику __attribute__((visibility("hidden")))
и может переопределить приложение scope класса __declspec(dllexport)
?
Ответы
Ответ 1
Документация MSDN дает представление о том, как это можно сделать. Здесь образец.
DLL_declspec.h:
#elif defined(BUILD_DLL)
#define DLL_DECLSPEC __declspec(dllexport)
#else
#define DLL_DECLSPEC __declspec(dllimport)
#endif
Чтобы экспортировать весь класс:
#include "DLL_declspec.h"
class DLL_DECLSPEC TestExport
{
public:
TestExport();
~TestExport();
std::string getName();
int getID();
};
Чтобы экспортировать только выбранные элементы класса:
#include "DLL_declspec.h"
class TestExport
{
public:
DLL_DECLSPEC TestExport();
DLL_DECLSPEC ~TestExport();
DLL_DECLSPEC std::string getName();
int getID();
};
Ответ 2
Я никогда не делал такого, но после документации MSDN это должно быть возможно.
Вы не должны указывать __declspec
на уровне класса и указывать только __declspec(dllexport)
для членов, которые вы хотите.
Надеюсь на эту помощь.