看板 C_and_CPP 關於我們 聯絡資訊
常常聽到同事會提到: 這樣interface會change耶 對方程式要重新build不太好 我想他指的是 對方拿到 dll+header 只要他exe不重新build 我只要interface不change 他只要替換dll exe應該就正常執行 但我稍微問一下他們似乎變成 .h有改動 = interface change... 我覺得怪怪的 我觀念是 只要你.h 裡面的virtual function 不管是宣告順序或是加入一些其他virtual function 導致vtable存放的位址有順序上的改變 雖然dll替換了 但.h沒有換 沒有重新編譯 exe執行才會壞吧? 如果我只是在.h多宣告一個普通member function或是data 沒動到vtable 對方雖然沒重新build 就算要重新build + 沒有替換.h 應該還是可以link的到我dll正確的function 只是沒辦法用我新加的function不是嗎? 舉個例子 如果我現在class給對方使用(但我忘了寫copy constructor) 事後 我想加一個copy constructor上去 所以我.h寫了個 XXX(X&); cpp做了一大堆定義 對方照理講 如果沒用到copy constructor的話 應該exe根本不需要重新build吧?? 想確認一下我觀念... ps. 我有看到一些寫法類似在private只保留一個Imp指標(包一堆data or function) 把所有實作都搞在cpp 查了一下 似乎是bridge pattern... 但這個pattern應該不是用來避免interface change吧? 只不過可以把資料包的更隱密 讓對方用妳dll 看到.h不會洩露太多private資料 也不用給別人看到....???? 如有錯誤請大力指點.... 謝謝各位 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 123.192.93.10
HudsonE:interface 會 change 真是有趣的用詞... XD 06/03 00:28
QQ29:其實我也不知道確切意思是啥? 但很想知道原因 06/03 00:35
QQ29:我應該把"會"提到 前面嗎= = 會interface change? 06/03 00:35
tinlans:查書都查錯...那是 bridge pattern。 06/03 00:36
tinlans:還有很多別名,像是 pimpl idiom、compilation firewalls 06/03 00:37
QQ29:是喔 我查網路的 因為我根本不知道那啥 但從code看好像是我 06/03 00:38
QQ29:講的行為嗎?? 06/03 00:39
QQ29:改一下 06/03 00:39
※ 編輯: QQ29 來自: 123.192.93.10 (06/03 00:39)
tinlans:主要是避免你改一點東西,很多東西都要重編。當然藏東西又 06/03 00:40
tinlans:是另一回事。你也能用 C++ 爸爸教的 private header files 06/03 00:40
tinlans:來藏東西。這些技巧的用意本身只是降低相依性。 06/03 00:40
QQ29:T大意思是bridge pattern也可以避免改一點要重編? 06/03 00:43
QQ29:那這樣我上面的觀念不就錯了嗎@@ 06/03 00:43
tinlans:至於 vtable 沒動到,只是加 non-virtual function 究竟 06/03 00:44
tinlans:要不要重編。基本上每個 function 都有佔一個 address, 06/03 00:44
tinlans:如果你沒把握原本沒動到的 function 在新編出來的檔案裡 06/03 00:45
tinlans:還是佔同一個 address 的話,那當然要重編比較保險。 06/03 00:45
tinlans:大多數自動型的編譯系統,是看到 .h 的檔案時間比 object 06/03 00:47
QQ29:所以這也是不一定嗎? 加function有風險就是了? 06/03 00:47
tinlans:files 還新,就把 include 它的檔案全部 rebuild 了。 06/03 00:47
QQ29:那我自己加copy cstr也會有風險嗎? 不過這又想問了 06/03 00:49
QQ29:compile我不寫copy cstr他會幫我加 但我現在寫了他應該還是在 06/03 00:49
QQ29:同一個位置嗎??還是也不一定... 06/03 00:49
tinlans:其實大部分的狀況下是沒什麼風險,除非你在很特殊的環境。 06/03 00:51
tinlans:不然 symbol 跟 address 的問題,loader 會幫你搞定。 06/03 00:51
tinlans:如果是在沒有 OS 的 embedded system,我就不能跟你保證。 06/03 00:52
tinlans:但是我不知道你的工作性質,所以先假設最壞狀況。 06/03 00:54
tinlans:簡單說,不是在很特殊的環境,增加 non-virtual 沒差。 06/03 00:55
tinlans:在 ps. 之前講的基本上都沒什麼問題。 06/03 01:01
QQ29:謝謝T大解釋 不過想問一下您說的 每個function都有個address 06/03 01:15
QQ29:那這address是記錄在哪裡呢?? 06/03 01:15
QQ29:我觀念不好但我自己測試 是我拿到編好的dll+h 我提供一個 06/03 01:16
QQ29:createInstance後 取得instance就可以用->去存取.h有的func了 06/03 01:17
QQ29:他位址會因為我.h宣告順序不同 而改變嗎?? 06/03 01:18
QQ29:不太了解細部運作原理....我自己測試是 如果不提供createInst 06/03 01:19
QQ29:ance 的話 就必須要提供lib檔給使用者 他才能自己new instanc 06/03 01:20
QQ29:e 不然就link錯誤...但這跟 function的address有什麼關聯嗎 06/03 01:20
QQ29:我也不懂= =所以想請教一下 謝謝指教! 06/03 01:21
tinlans:windows 的話,你要自己查資料,我也沒辦法回答你。 06/03 01:46
tinlans:其它平台用 ELF 格式的話,動態的 symbol 是用 GOT, 06/03 01:47
tinlans:然後透過 PLT 去跳。 06/03 01:47
tinlans:我只知道 windows 的話,動態連結的東西要同時提供 lib 跟 06/03 01:48
tinlans:dll,不提供 lib 的話會不能擴充。使用 ELF 格式的平台大 06/03 01:48
tinlans:都只要 .h 跟 .so 而已。 06/03 01:48
tinlans:但是你的這個問題,我覺得可能在 runtime 才 load 可能會 06/03 02:02
tinlans:有解。想在 linking time 解決的話我就不曉得了。 06/03 02:02
QQ29:謝謝T大 剛剛試著呼叫non virtual function沒給lib他就說link 06/03 10:31
QQ29:不到.... 我也不知道怎麼解釋 自己心得是 對方用你class的 06/03 10:32
QQ29:virtual fun只要你提供createinstance就不需lib 06/03 10:32
QQ29:但如果用到non-virtual的 就要lib了 ... 06/03 10:33
Bencrie:Windows就找 PE (portable executable) 格式吧 06/03 10:41
Bencrie:function address要有宣告dllexport才會紀錄在匯出表 06/03 10:42
Bencrie:不然應該都是寫死在.text裡的常數 06/03 10:43
TeaEEE:如果是在windows下 連member data順序的變動都有可能會出錯 06/03 13:22
tinlans:data member 只是一個常數 offset,動到的話不管在哪個 06/03 14:24
tinlans:平台都會出問題吧?member function 是 symbol, 06/03 14:24
tinlans:狀況不太一樣... 06/03 14:24