簡體   English   中英

鏈接靜態和動態庫時違反 ODR

[英]ODR violation when linking static and dynamic library

鏈接包含不同版本的 boost 的靜態 cpp 庫和動態 cpp 庫是否會違反 ODR?

我正在開發一個 iphone 應用程序。 對於最終的可執行文件,我需要鏈接一個靜態庫(比如 libstatic1.a)和一個動態框架(比如 libdyanamic1)。

libstatic1.a 包含某個版本的 boost,比如 boost 1.x,而 libdynamic1 包含另一個版本的 boost,比如 boost 1.y。 現在鏈接這兩者的最終可執行文件是否會違反 ODR 規則?

libdynamic1 中的符號可見性:我使用nm -g -C libdynamic1檢查了 libdynamic1 中存在的符號,並觀察到 ​​boost nm -g -C libdynamic1和 boost 文件系統的符號存在於列表中。

如果我違反了 ODR,我有哪些選擇來處理這種情況? (到目前為止,我已經在多個設備上測試了可執行文件,並且沒有遇到任何問題。)

該標准僅討論“程序”,其中“程序”是一組“鏈接在一起”的翻譯單元,每個單元由一系列聲明[basic.link] 組成 爭論 O​​DR,它也只與“程序”有關,當涉及到涉及動態庫的問題時,並不是那么簡單。 由於“程序”需要包含main函數[basic.start.main]/1 ,因此動態鏈接庫本身通常不符合“程序”的要求。

嚴格來說,我認為動態庫只能被視為另一組翻譯單元,它們與其他單元“鏈接”以形成最終程序。 因此,只有在所有圖像都加載到內存中並且動態鏈接完成后,程序才會真正完成(運行時動態鏈接似乎使問題進一步復雜化,但我猜在這里可以忽略)。 從這個意義上說,您的問題中描述的程序(鏈接靜態和動態庫,其中每個庫都使用不同版本的 boost)幾乎肯定會違反 ODR,因為您將擁有多個翻譯單元,例如,使用相同實體的不同定義[basic.def.odr]/12

然而,在實踐中,這個問題高度依賴於平台和工具鏈。 在 ABI 級別,您通常會發現符號可以具有的鏈接類型比您在 C++ 中的語言級別發現的更加不同。 例如,在 Windows 上,您通常必須在構建動態庫時明確指定應導出哪些符號,默認情況下所有名稱都是庫的內部名稱。 另一方面,在基於 ELF 的 Linux 上,情況並非如此。 但是,您似乎可以使用-fvisibility=hidden選項將 GCC 切換到更類似於 Windows 的默認設置,其中您的庫將僅導出您明確告訴它的內容。 請注意,您不能在庫導出的界面中與 boost 有任何關系,因為這顯然會導致您的情況出現未定義的行為......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM