在ELF目標上,如果我有class Foo
,並且我通過class __attribute__((visibiility("default"))) Foo
等聲明提供了default
可見性,那麼我可以通過使用__attribute__((visibility("hidden"))
明確註釋它們來有選擇地豁免該類別的某些成員具有default
可見性。這可以是內聯方法不應該形成ABI的一部分,因此,如果他們正在構建限定class Foo
庫時發出的,它們不會被導出,或用於private
成員或類型內class Foo
也不應該形成的部分有用的其ABI。如何在每個成員的基礎上覆蓋類作用域__declspec(dllexport)註釋?
然而,在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")))
的語義,並且可以覆蓋__declspec(dllexport)
的類範圍應用程序?
僅供參考_「內聯方法是不應構成ABI的一部分,「_內聯並不意味着內聯(除非使用編譯器特定的內聯擴展)。所以它們是ABI的一部分,內聯甚至不是大多數現代編譯器的暗示。 –
另外,如果該類的公共方法調用私有方法(同一類)並且公共方法在客戶端應用程序中內聯;那麼私有方法需要是鏈接器可見的並且構成ABI的一部分。 –
@Richard Critten對於你的第二個評論,完全同意,但這很容易理解 - 只是不要內聯那些必須要求私人成員的公共方法,而且在實踐中還沒有出現。對於你的第一條評論,我同意inline對於編譯器來說「甚至不是提示」,但它確實對鏈接有影響。考慮'-fvisibility-inlines-hidden'對ELF平臺的影響。我關於內聯不構成ABI一部分的論點取決於這樣一個觀點,即只要內聯方法簡單地委託給ABI方法,客戶端和庫的意義是否分歧並不重要。 – acm