如何基于每个成员覆盖类范围的__declspec(dllexport)注释?

How can I override a class scoped __declspec(dllexport) annotation on a per-member basis?

本文关键字:declspec dllexport 注释 范围 何基于 成员 覆盖      更新时间:2023-10-16

在 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)

希望这有帮助。