看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《Rx400 (American Dream)》之銘言: : 自己寫了一個C++程式,已經測試過, : 但是學長要求要把我寫的C++整合到C裡面, : 我寫的C++都是用OO去寫,還用了stl, : 我試著在class用extern "C"包起來,再寫個簡單的C,把c++的header檔引進來 : 但compile一下就掛了 : 請問有相關的資料可以參考嗎? : 或者是要把所有的class改寫成struct? 因為你用到 OO, 所以我假定你的 class 裡面有 virtual 成員。 這樣 struct 搭 #ifdef __cplusplus 去隔開 member function 的方法就會不能用了, 因為必須是 POD 才能跟 C 的 struct 有相同的 layout。 不過還是有一種傳統的方法可以用。 假設你的 class 是: class MyClass { public: virtual void foo(); virtual MyClass *bar(int var); ... private: ... }; 你可以造出一個給 C 用的 header file 像是這樣: struct MyClass; // C/C++ 只要有前置宣告就能用它的 pointer #ifdef __cplusplus extern "C" { #endif void foo(struct MyClass *obj); struct MyClass *bar(struct MyClass *obj, int var); ... #ifdef __cplusplus } #endif 然後開一個 C++ source file 檔去寫上面 foo 和 bar 的實作 (這個檔因為是 C++ source file 所以當然可以看到 class 定義式): extern "C" void foo(struct MyClass *obj) { obj->foo(); } extern "C" struct MyClass *bar(struct MyClass *obj, int var) { return obj->bar(var); } ... 這樣 C program 就不需要看到 struct MyClass 的定義式。 它們的 object files 也能互相 link。 不過 linker 一定要是 C++ mode (GCC 的話就是下 g++ 而不是 gcc), 而且有 main() 的那個檔案最好用 C++ mode 編譯, 因為某些 compiler 可能會放一些 C++ 特有的啟動和結束碼在 main() 開頭跟結尾。 像是 global object (如 cin/cout 這些東西) 的初始化動作, 你用 C mode 的話就算有 link 到 C++ lib (如 libstdc++.so) 也未必會 work。 main() 如果真的只能用 C compiler 編過的話, 那也很簡單就直接把它改名如 legacy_main(), 然後你開一個 C++ source file 寫一個空的 main() 去 call 它就好了。 其實這種避免 C 看到 class 定義式的技巧很早就有了。 它在純 C 的年代就很流行, 因為純 C 年代的工程師就已經有封裝的觀念了。 常常會有不希望 struct 的內部結構被人知道太多的需求出現, team work 的話甚至防範的對象還包括自己的同事。 當時的做法就是直接把 struct 定義式塞在 .c 或是不會公開的 .h 檔內, 這樣別人就沒辦法直接存取你 struct 變數裡的成員, 只能用你提供的 functions 去使用這個 struct 藉此達成封裝和資訊隱藏的目的。 -- Ling-hua Tseng ([email protected]) Department of Computer Science, National Tsing-Hua University Interesting: C++, Compiler, PL/PD, OS, VM, Large-scale software design Researching: Software pipelining for VLIW architectures Homepage: https://www.tinlans.org -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.160.116.129 ※ 編輯: tinlans 來自: 118.160.116.129 (11/07 22:29)
elfkiller:頭推 11/07 22:39
remmurds:推推推 11/07 22:44
remmurds:不過原PO在看完這篇後可能會覺得不如把class改成struct 11/07 22:47
remmurds:還比較快吧-.-" 11/07 22:47
Rx400:同一個研究所的等級怎嚜會那麼多,謝謝指教 11/07 23:00
QQ29:看T大的個人網頁 超威的 = = 11/07 23:02
awashharp:個人網頁被Firefox擋住了…憑證… 11/07 23:35
VictorTom:推一下....:) 11/08 00:15
tinlans:class -> struct 是必須的,但有 virtual function 的話, 11/08 03:02
tinlans:layout 跟 C 未必會通,因為有藏一個 vptr,你不能假設它 11/08 03:03
tinlans:在物件資料區段的開頭還是結尾或任何地方。 11/08 03:03
kikiqqp:推 這作法好 11/08 10:07
kkc:T大真的很威! 11/08 21:50
saxontai:推! 11/09 01:47
james732:很強大的分享,推!! 11/09 01:51
revivalworld:推 11/09 12:36
HudsonE:我看到很懷念的 MudOS... 11/09 16:28
hubert100:t大的老闆是我大學老師的老闆 11/10 12:46
theee:T大和我同鄉,第一次看到同鄉 XD 11/19 23:52
※ 編輯: tinlans 來自: 118.160.106.161 (11/22 13:03)