在 ELF 目标上,如果我有class Foo
并且我通过像class __attribute__((visibiility("default"))) Foo
这样的声明赋予了它default
可见性,那么我就可以通过使用__attribute__((visibility("hidden"))
显式注释它们来有选择地免除类的某些成员具有default
可见性。这对于不应构成 ABI 一部分的内联方法很有用,因此,如果在构建定义class Foo
库时发出它们,则不会导出它们,或者对于class Foo
中也不应构成其 ABI 一部分的private
成员或类型。
但是,在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;
};
在现实世界的实现中,我希望它们之间的差异隐藏在宏后面。
我忽略了一些具有__attribute__((visibility("hidden")))
语义并且可以覆盖__declspec(dllexport)
类范围应用的__declspec
?
MSDN 文档给出了如何完成它的想法。下面是一个示例。
DLL_declspec.h:
#if 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();
};
我从来没有做过这样的事情,但是按照 MSDN 文档应该可以。
不应在类级别指定任何__declspec
,而只为所需的成员指定__declspec(dllexport)
。
希望这有帮助。