C++库文件导出可见性
生活随笔
收集整理的這篇文章主要介紹了
C++库文件导出可见性
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
導出符號
C++中除了語言級別的訪問特性(公有、私有和保護)外,還有兩個相關的概念允許暴露API中的符號,它們位于物理層次,分別是:
外部鏈接
外部鏈接這個術語是指一個編譯單元中的一個符號可以被其他編譯單元訪問,而導出是只在庫文件中可見的符號。只有外部鏈接才可以導出。
我們先看下外部鏈接,這是決定客戶是否可以訪問共享庫中符號的第一步。特別地,除非采取強制措施,否則.cpp文件中(文件作用域)的全局自由函數和變量會有外部鏈接。
舉個栗子:
上述代碼中盡管已經將這些函數和變量限制在一個.cpp文件之內,然而機智的客戶還是可以在自己的程序中訪問這些符號,這樣他們就能夠不通過公有API直接調用全局函數并修改全局狀態,從而破壞封裝性。
// declare the external linkage elements of myobject.cpp extern void FreeFunction(); extern int INTERNAL_CONSTANT; extern std::string Filename; // 不通過公有API調用私有函數和修改全局變量 // call a function hidden within the myobject.cpp module FreeFunction();// access a constant defined within myobject.cpp std::cout << "Internal constant = " << INTERNAL_CONSTANT << std::endl;// change global state within myobject.cpp Filename = "different.txt";對于以上外部鏈接泄露問題,有一下解決方法
- 靜態聲明。預先考慮使用static關鍵字聲明函數和變量。它將函數或變量指定為內部鏈接,從而不能在其所在的編譯單元之外訪問
- 匿名命名空間。使用匿名命名空間更加符合C++的慣例用法,把文件作用域的函數和變量封裝進匿名命名空間。這是一個更好的方法,因為它能夠避免污染全局命名空間。可以按照如下方式實現:
導出可見性
可以通過編譯器特定的符號,指定共享庫中哪些符號對外可見
- Microsoft Visual Studio的DLL文件默認是不可訪問的,必須顯示聲明哪些函數導出DLL才能對外可見。當需要導出時指定__desclspec(dllexport), 在客戶端程序想要訪問需要指定__desclspec(dllimport)才能訪問符號。
- GNU C++編譯器默認情況下,所有符號對外可見。不過可以通過__attribute__可見性修飾符隱藏一個符號,當然GNU C++4.0以上可以通過__fvisibility_hidden標記,它強制所有聲明在默認情況下隱藏可見性,個別符號需要聲明__attribute__((visibility(“default”)))顯示導出。使用__fvisibility_hidden還可以顯著的提升動態庫加載時的性能,并生成更小的庫文件。
關注微信號,一起學習C++/go/vue
添加群一起討論一起進步
總結
以上是生活随笔為你收集整理的C++库文件导出可见性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件测试——实验二
- 下一篇: Linux CPU cache