[英]How do I combine a standalone c application into a c++ one?
我正在開發一個 C++ 應用程序(稱為recorder.cpp
),其中包含來自其他地方的一些 C++ 庫(必須使用 c++14,所以我被困在這方面)。 目前我的應用程序正在運行,但它只是根據外部庫和命令行參數進行配置。
有一個單獨的 C 應用程序(稱為receiver.c
),它獨立工作,我基本上想與recorder
結合使用。 我認為簡單的方法是將所有receiver
復制並粘貼到recorder
,但這似乎有點多余(更不用說如果我將來對receiver
進行修改,我將需要在recorder
進行相同的更改)。 所以我試圖弄清楚是否有辦法鏈接它們,以便我可以從recorder
應用程序呼叫receiver
recorder
。 我知道我不能只調用receiver
的 main(),但我不確定是否有辦法構建receiver
,使其更像一個庫,但仍然可以構建為獨立的應用程序。
“......我試圖弄清楚是否有辦法將它們聯系起來,以便我可以從錄音機應用程序中呼叫接收者。”
是 - 但更簡單、更直接的方法是將reciever.c
代碼(減去它的main()
函數)與 C++ 代碼一起復制。 這將要求C
代碼中沒有違反C++
規則的語法。 (例如,在 C++ 中需要強制轉換malloc()
的返回值,但在 C 中不推薦。)但是因為大多數 C 語法完全與C++
兼容,所以應該很少或不需要修改。 現在你所有的代碼都在一起了,可以簡單地編譯為C++
。
然而,鏈接方法需要編譯獨立程序的所有函數(同樣,將main()
函數省略到庫中。例如 DLL 或共享庫。可以使用extern "C" { ... } within the
鏈接該庫extern "C" { ... } within the
C++ 頭文件中以包圍C
庫文件中定義的C
函數原型。包圍中的那些函數將使用C
鏈接而不是C++
進行編譯。一個簡單的例子:
// C++ code
extern "C" void f(int); // one way
extern "C" { // another way
int g(double);
double h();
};
void code(int i, double d)
{
f(i);
int ii = g(d);
double dd = h();
// ...
}
請注意,鏈接中包含以下語句: “...此外,您需要閱讀本節的其余部分,以了解如何使您的 C 函數可由 C++ 調用和/或您的 C++ 函數可由 C 調用。”
編輯以從評論中添加信息:
關於創建庫。 然后該庫可以被兩個程序使用,而不是在兩個地方維護。 這會使版本控制復雜化,並且如果這兩個程序將來出現分歧,可能會出現未來問題。 另請注意,也可以使用靜態庫而不是共享庫。 隨着未來的變化發生,這些方法具有不同的版本影響。 (來自@Avi Berger)
...或者,如果您的意圖是擁有一個通用的 *.c 文件,以便為一個應用程序所做的更改很容易包含在另一個應用程序中,那么您無需創建庫,而只需在 .o 文件中進行鏈接。 (來自@Goswin von Brederlow)
只需按照通常的方式編譯目標文件recorder.o
和receiver.o
。 確保它們沒有main()
函數:要么#ifdef
有條件地輸出它,要么(更好)在每個程序(例如recorder_main.cpp
和receiver_main.c
)的自己的目標文件中編譯它。
使用后一種方法,Makefile 非常簡單,因為我們可以讓 Make 使用其內置規則來正確生成目標文件。 我們所要做的就是告訴它如何鏈接:
receiver: receiver_main.o receiver.o
$(LINK.o) $^ $(LDLIBS) -o $@
recorder: recorder_main.o recorder.o receiver.o
$(LINK.cc) $^ $(LDLIBS) -o $@
請注意,我們需要將recorder
與 C++ 鏈接器(理解名稱修改)而不是 C 鏈接器鏈接。
如果您想要單獨的源目錄,可以使用 Makefile 中的VPATH
輕松管理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.