[問題] static lib 實作 singleton 觀念

看板C_and_CPP作者 (小嫩)時間5年前 (2019/03/25 23:24), 編輯推噓5(5025)
留言30則, 9人參與, 5年前最新討論串1/1
最近遇到一個問題 無法理解行為為什麼會是這樣. 我在某static lib 稱作libS.a 裡面實作了一個簡單的singleton (介面為GetInst) 我有兩個dynamic lib, (libA.so, libB.so) 都使用這S.a , 而E.exe是link 這兩個.so 而沒有直接使用.a 附上Cmake file 可以比較明確知道關係 set(CMAKE_CXX_VISIBILITY_PRESET hidden) add_library(S STATIC s.cpp) add_library(S2 STATIC s2.cpp) <==這邊故意改成S2 讓他變成兩個.a add_library(A SHARED a.cpp) target_link_libraries(A PRIVATE S) add_library(B SHARED b.cpp) target_link_libraries(B PRIVATE S2) <==故意, 原本寫S也是一樣結果 add_executable(E main.cpp) target_link_libraries(E PRIVATE A B S S2) 我的問題是 因為是.a 我用nm看A.so跟B.so裡面都有 "GetInst"這symbol 我預期他們各自有獨立的singleton, 意思是從GetInst拿到的instance要不一樣 我用E.exe去驗證這件事, 沒想到 拿到的竟然是一樣的instance, 我故意夾個log 並且把s.cpp 複製一份叫做s2.cpp 然後產出libS2.a 如上CMake所述 我能發現的是 E.exe執行的時候 最後呼叫到static library的時候 他只會走其中一個 實作 這邊給我的感覺可能扯到ODR, 但我整件事兜不起來覺得很困惑 如果今天libS.a不是static而是libS.so, 整件事應該相當合理 可是它是static lib 最後卻只有一份 是有什麼設定我沒有做 還是這非常正常....如果是可否給我一些觀念上的補充 因為以我這簡單的lib間的關係 難道"兩個.so 用到不同的.a 而這不同的.a有相同symbol 最後產出的exe 只會選擇走一 個實作" 這件事很難碰到嗎? 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 27.247.94.8 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1553527468.A.0C4.html

03/25 23:46, 5年前 , 1F
這樣不是違反odr?
03/25 23:46, 1F

03/26 10:13, 5年前 , 2F
E.exe 是怎麼call libA.so libB.so去拿instance的?
03/26 10:13, 2F

03/26 10:14, 5年前 , 3F
猜測只link到了libA.so/libB.so其中一個.
03/26 10:14, 3F

03/26 11:49, 5年前 , 4F
liba and b.so都各自開一個不同名字的function 裡面
03/26 11:49, 4F

03/26 11:49, 5年前 , 5F
都是return GetInst(); E.exe去 呼叫這兩個不同名
03/26 11:49, 5F

03/26 11:49, 5年前 , 6F
函數 但得到同一個物件
03/26 11:49, 6F

03/26 14:06, 5年前 , 7F
他們不是叫同一個 GetInst 嗎
03/26 14:06, 7F

03/26 14:25, 5年前 , 8F
好奇問一下 為什麼寫了Singleton卻還要弄兩份XD
03/26 14:25, 8F

03/26 14:29, 5年前 , 9F
希望是同一份 ,但想想覺得可能會兩份,測試起來 竟
03/26 14:29, 9F

03/26 14:29, 5年前 , 10F
然真的是一份 ,無法理解為什麼,想知道中間的差異
03/26 14:29, 10F

03/26 14:29, 5年前 , 11F
難道載入exe的時候也會扯到odr?
03/26 14:29, 11F

03/26 15:27, 5年前 , 12F
target_link_libraries(E PRIVATE A B S S2) 這裡?
03/26 15:27, 12F

03/26 16:49, 5年前 , 13F
@ketrobo: 這部分 實驗 加跟沒加 有沒有差別,結論是
03/26 16:49, 13F

03/26 16:49, 5年前 , 14F
沒差都一樣行為,但我忘記貼在這邊之前刪除,謝謝
03/26 16:49, 14F

03/26 17:55, 5年前 , 15F
libA.so 和 libB.so 有各自的 GetInst,但是 dynamic l
03/26 17:55, 15F

03/26 17:55, 5年前 , 16F
inker 只會連結到A或B裡面的其中一個。(應該是看誰先被
03/26 17:55, 16F

03/26 17:55, 5年前 , 17F
載入)
03/26 17:55, 17F

03/26 17:55, 5年前 , 18F
把 -Wl,-Bsymbolic 加到 CXXFLAGS 裡,應該就會拿到不
03/26 17:55, 18F

03/26 17:55, 5年前 , 19F
同個 instance 了
03/26 17:55, 19F

03/26 18:46, 5年前 , 20F
意思是 lib ab 各自有同名symbol, 但照順序載入 發現
03/26 18:46, 20F

03/26 18:46, 5年前 , 21F
撞名 所以就只載入最一開始的那份,所以libb.so 呼叫
03/26 18:46, 21F

03/26 18:46, 5年前 , 22F
到的getinst是a.so的那份?
03/26 18:46, 22F

03/26 20:39, 5年前 , 23F
我有寫過一個class,也是需要兩份,裡面各自需要不同的st
03/26 20:39, 23F

03/26 20:39, 5年前 , 24F
atic member,我是用template處理的,給你參考
03/26 20:39, 24F

03/26 21:01, 5年前 , 25F
03/26 21:01, 25F

03/27 08:01, 5年前 , 26F
這個應該叫 global symbol interpose
03/27 08:01, 26F

03/27 11:23, 5年前 , 27F
補充一下#1RViGNxg我有回,基本上是依SysV ABI的規則解
03/27 11:23, 27F

03/27 11:23, 5年前 , 28F
簡單想成, -la -lb, 在.a和.so的結果會大同小異
03/27 11:23, 28F

03/27 11:24, 5年前 , 29F
loader用DT_NEED的順序解,多層依BFD找. DT_NEED的順序是
03/27 11:24, 29F

03/27 11:25, 5年前 , 30F
linktime決定, 所以 A B 就決定是找 A 的版本. 大致這樣
03/27 11:25, 30F
文章代碼(AID): #1ScFAi34 (C_and_CPP)