[問題] template funtion/class in dll

看板C_and_CPP (C/C++)作者 (動き出す時間...)時間6天前 (2025/04/09 22:46), 10小時前編輯推噓2(2032)
留言34則, 4人參與, 3天前最新討論串1/1
開發平台(Platform): (Ex: Win10, Linux, ...) Win10 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出) MSVC 問題(Question): 請教template function在dll裡面兩種實作 補充說明(Supplement): 眾所周知 template function實體化T有兩種方式 1. 直接把template function寫在header 2. template function寫在cpp, 需要另外宣告T實體化 今天假設template寫在一個dll裡面 而我有另外一隻程式MyApp需要用這個dll 在上述兩種實體化template狀況 產生兩種不同的結果 以下是我跟chatgpt討論的結果 想跟板上各位先進請教是否哪裡有錯 1. 當template function實作完全寫在header裡面 則MyApp在include這個dll header時 T實體化 template程式碼完全被展開後直接編譯 然後變成MyApp的一部分 此時dll template header 相當於"直接變成MyApp的header" 由於編譯出來的程式碼直接變成MyApp的一部分 如果用debug設定template function中斷點 會看到stack顯示 MyApp::func() 而非 dll::func() (示意) 2. template function寫在cpp裡面 因為需要額外做實體化宣告T 產生了一個問題 如果MyApp使用template需要的T type 沒有在dll裡面宣告實體化 則compile會報錯 ex: dll裡面只有明確宣告T為int 但是MyApp使用template時希望T為float 因此這種方式需要確保MyApp使用template所需求T 已經明確在dll裡面被實體化宣告 這種狀況跟一般function沒有差別 template function是存在在dll裡面 debug設定中斷點就會看到dll::func() 兩者差異 A. template function在1的狀況下是在MyApp裡面, 而2是在dll裡面 B. 假設要修改function 則1的狀況: dll重build後更新dll檔給MyApp執行測試 -> 沒用 dll重build後把lib檔給MyApp重新link -> 沒用 原因在於 因為header已經變成MyApp的一部分 所以要"直接修改MyApp include的dll header" 而非 "dll project底下的header" 除非MyApp include path直接指向dll project的目錄讓上述兩者是同一個檔案 但一般來說不會這樣做 不同project會分不同目錄 dll會經過正常release build後打包header/lib/dll再給其他project使用 由於這種狀況header相當於直接變成MyApp的 因此要debug測試 直接修改include path裡面的header即可 跟dll project本身完全無關 至於2當然就沒甚麼好說的 dll重build後更新給MyApp重測即可 C. Code size 1的狀況 template function是直接跟MyApp包在一起的 因此如果dll本身也有其他地方用到template function 則會變成MyApp跟dll兩邊都有template function的情況 至於2當然就沒啥好說的 chatgpt告訴我 STL lib就是採用把template class function全部寫在header的作法 因為STL開發者不可能知道使用者會用vector/list/map去包甚麼東西 所以根本不可能採用第二種方式"事先"宣告template實體化(更何況user也可能自訂型別) 以上 如果有錯的話還請版上各位指教 感謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 36.230.229.121 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1744209989.A.93D.html ※ 編輯: Keitaro (36.230.229.121 臺灣), 04/09/2025 22:46:55

04/10 03:55, 6天前 , 1F
概念上應該還行, 然後這裡有個和 1. 相關用語「僅檔頭庫」
04/10 03:55, 1F

04/10 03:56, 6天前 , 2F
(header-only library) 這是模版函式庫的常用實作方式
04/10 03:56, 2F

04/10 03:58, 6天前 , 3F
如你所說, 由於僅有檔頭所以跟 dll/lib 這種預編函式庫
04/10 03:58, 3F

04/10 03:58, 6天前 , 4F
基本上就沒什麼關係了
04/10 03:58, 4F

04/10 03:59, 6天前 , 5F
那這裡可能就有個 XY 問題了: 因為 C++ 這個機制的關係
04/10 03:59, 5F

04/10 03:59, 6天前 , 6F
這篇文章的大前提「dll 中的模版」其實是個很奇怪的需求
04/10 03:59, 6F

04/10 04:01, 6天前 , 7F
我會想問為什麼會有把模版編進 dll 的需求?
04/10 04:01, 7F

04/10 08:10, 5天前 , 8F
感謝樓上回覆 我也是看到同事寫template class放在一個
04/10 08:10, 8F

04/10 08:10, 5天前 , 9F
dll project其中一個header裡面 要debug都沒辦法設中斷
04/10 08:10, 9F

04/10 08:10, 5天前 , 10F
點去查資料才了解template的實作竟有這樣的差異
04/10 08:10, 10F

04/10 08:12, 5天前 , 11F
如您所說 這個template class其實已經跟這個project的屬
04/10 08:12, 11F

04/10 08:12, 5天前 , 12F
性是dll/lib/exe完全無關了 也不知道寫code的前同事是否
04/10 08:12, 12F

04/10 08:12, 5天前 , 13F
考慮過這問題:)
04/10 08:12, 13F

04/10 08:21, 5天前 , 14F
補充 chatgpt告訴我 c++20新增的module概念 可以支援把
04/10 08:21, 14F

04/10 08:21, 5天前 , 15F
template class/function放在dll cpp裡面了
04/10 08:21, 15F

04/10 21:39, 5天前 , 16F
header only lib怎麼會有dll?dll裡面只有translation un
04/10 21:39, 16F

04/10 21:39, 5天前 , 17F
it吧,難道我那邊理解錯誤
04/10 21:39, 17F

04/12 20:23, 3天前 , 18F
在過去,template 的資訊在編譯後就完全消失了,這帶來了
04/12 20:23, 18F

04/12 20:24, 3天前 , 19F
很多不便,後來做 LTO 時各家編譯器開始設法保存原始碼的
04/12 20:24, 19F

04/12 20:25, 3天前 , 20F
資訊到編譯後的產物裡,這也是為什麼你會問到 modules
04/12 20:25, 20F

04/12 20:26, 3天前 , 21F
可以這樣的原因,但它本質上其實並沒有多少改變。
04/12 20:26, 21F

04/12 20:27, 3天前 , 22F
另外你的用語是有問題的,template 應該放在後面,兩個
04/12 20:27, 22F

04/12 20:27, 3天前 , 23F
名詞放在一起時是名詞修飾名詞,後面的名詞才是主體。
04/12 20:27, 23F

04/12 20:28, 3天前 , 24F
class template、function template 這樣寫才對。
04/12 20:28, 24F

04/12 20:28, 3天前 , 25F
至於為什麼要強調這個?因為 template 在 C++ 就是一種
04/12 20:28, 25F

04/12 20:29, 3天前 , 26F
還沒有實體的骨架這樣的東西,需要被實體化。
04/12 20:29, 26F

04/12 20:31, 3天前 , 27F
你顛倒過來寫,如果不是英語不好,那就是基礎概念理解上
04/12 20:31, 27F

04/12 20:31, 3天前 , 28F
存在嚴重的誤區。
04/12 20:31, 28F
感謝指正

04/12 20:45, 3天前 , 29F
「相當於直接變成MyApp的header」這描述也很奇怪,header
04/12 20:45, 29F

04/12 20:45, 3天前 , 30F
的從屬性是跟著 project 走,所以你其它地方描述倒是沒啥
04/12 20:45, 30F

04/12 20:46, 3天前 , 31F
問題,只是 header 寫出來就是給人家 include 的,只要
04/12 20:46, 31F

04/12 20:46, 3天前 , 32F
include 了就是用到了它,但從屬關係並不會因此改變。
04/12 20:46, 32F
哦這一點是我的盲點 的確header在c++裡面只要有include就算是"project有用到它" 不需要vcxproj去設定include這個header 相比之下cpp檔就一定要設定才會compile 但平常我的project都還是會設定vcxproj會include header 這樣在visual studio的檔案總管那邊可以直接點開比較方便 我這邊的描述意思是"相當於MyApp的vcxproj有這個header"這樣的意思

04/12 20:47, 3天前 , 33F
不過這裡講的 header 從屬性是更抽象的概念,和 C++ 還有
04/12 20:47, 33F

04/12 20:48, 3天前 , 34F
它的編譯連結特性不存在任何關係。
04/12 20:48, 34F
※ 編輯: Keitaro (60.251.156.103 臺灣), 04/15/2025 17:44:01
文章代碼(AID): #1dzeX5az (C_and_CPP)
文章代碼(AID): #1dzeX5az (C_and_CPP)