作者Keitaro (动き出す时间...)
看板C_and_CPP
标题[问题] template function/class in dll
时间Wed Apr 9 22:46:27 2025
开发平台(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://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1744209989.A.93D.html
※ 编辑: Keitaro (36.230.229.121 台湾), 04/09/2025 22:46:55
1F:推 LPH66: 概念上应该还行, 然後这里有个和 1. 相关用语「仅档头库」 04/10 03:55
2F:→ LPH66: (header-only library) 这是模版函式库的常用实作方式 04/10 03:56
3F:→ LPH66: 如你所说, 由於仅有档头所以跟 dll/lib 这种预编函式库 04/10 03:58
4F:→ LPH66: 基本上就没什麽关系了 04/10 03:58
5F:→ LPH66: 那这里可能就有个 XY 问题了: 因为 C++ 这个机制的关系 04/10 03:59
6F:→ LPH66: 这篇文章的大前提「dll 中的模版」其实是个很奇怪的需求 04/10 03:59
7F:→ LPH66: 我会想问为什麽会有把模版编进 dll 的需求? 04/10 04:01
8F:→ Keitaro: 感谢楼上回覆 我也是看到同事写template class放在一个 04/10 08:10
9F:→ Keitaro: dll project其中一个header里面 要debug都没办法设中断 04/10 08:10
10F:→ Keitaro: 点去查资料才了解template的实作竟有这样的差异 04/10 08:10
11F:→ Keitaro: 如您所说 这个template class其实已经跟这个project的属 04/10 08:12
12F:→ Keitaro: 性是dll/lib/exe完全无关了 也不知道写code的前同事是否 04/10 08:12
13F:→ Keitaro: 考虑过这问题:) 04/10 08:12
14F:→ Keitaro: 补充 chatgpt告诉我 c++20新增的module概念 可以支援把 04/10 08:21
15F:→ Keitaro: template class/function放在dll cpp里面了 04/10 08:21
16F:推 wulouise: header only lib怎麽会有dll?dll里面只有translation un 04/10 21:39
17F:→ wulouise: it吧,难道我那边理解错误 04/10 21:39
18F:→ tinlans: 在过去,template 的资讯在编译後就完全消失了,这带来了 04/12 20:23
19F:→ tinlans: 很多不便,後来做 LTO 时各家编译器开始设法保存原始码的 04/12 20:24
20F:→ tinlans: 资讯到编译後的产物里,这也是为什麽你会问到 modules 04/12 20:25
21F:→ tinlans: 可以这样的原因,但它本质上其实并没有多少改变。 04/12 20:26
22F:→ tinlans: 另外你的用语是有问题的,template 应该放在後面,两个 04/12 20:27
23F:→ tinlans: 名词放在一起时是名词修饰名词,後面的名词才是主体。 04/12 20:27
24F:→ tinlans: class template、function template 这样写才对。 04/12 20:28
25F:→ tinlans: 至於为什麽要强调这个?因为 template 在 C++ 就是一种 04/12 20:28
26F:→ tinlans: 还没有实体的骨架这样的东西,需要被实体化。 04/12 20:29
27F:→ tinlans: 你颠倒过来写,如果不是英语不好,那就是基础概念理解上 04/12 20:31
28F:→ tinlans: 存在严重的误区。 04/12 20:31
感谢指正
29F:→ tinlans: 「相当於直接变成MyApp的header」这描述也很奇怪,header 04/12 20:45
30F:→ tinlans: 的从属性是跟着 project 走,所以你其它地方描述倒是没啥 04/12 20:45
31F:→ tinlans: 问题,只是 header 写出来就是给人家 include 的,只要 04/12 20:46
32F:→ tinlans: include 了就是用到了它,但从属关系并不会因此改变。 04/12 20:46
哦这一点是我的盲点
的确header在c++里面只要有include就算是"project有用到它"
不需要vcxproj去设定include这个header 相比之下cpp档就一定要设定才会compile
但平常我的project都还是会设定vcxproj会include header
这样在visual studio的档案总管那边可以直接点开比较方便
我这边的描述意思是"相当於MyApp的vcxproj有这个header"这样的意思
33F:→ tinlans: 不过这里讲的 header 从属性是更抽象的概念,和 C++ 还有 04/12 20:47
34F:→ tinlans: 它的编译连结特性不存在任何关系。 04/12 20:48
※ 编辑: Keitaro (60.251.156.103 台湾), 04/15/2025 17:44:01