c/c++靜態(tài)庫之間相互調(diào)用的實(shí)戰(zhàn)案例
本文主要介紹c語言寫的項目如何調(diào)用c++實(shí)現(xiàn)的庫和c++如何調(diào)用c語言實(shí)現(xiàn)的庫
一、c++項目如何調(diào)用c的庫(以靜態(tài)庫為例)
??示例:建立一個項目Stack_c.lib,將該項目中的棧的實(shí)現(xiàn)的代碼打包為一個靜態(tài)庫,再建立另一個c++的項目,并調(diào)用打包好的c實(shí)現(xiàn)的靜態(tài)庫里的棧的相關(guān)函數(shù)
1.將棧的源文件和頭文件拷貝一份到Stack_c.lib這個項目的路徑下
2.打包成靜態(tài)庫
??應(yīng)用好之后就點(diǎn)擊生成解決方案 ,之后就會生成一個Stack_c.lib的靜態(tài)庫了 (與項目名重名了,問題不大 不要在意)
生成后我們可以點(diǎn)開項目的所在目錄下 找到debug目錄 可以看到里面多了一個Stack_c.lib的靜態(tài)庫文件 表示打包成功!
??至此,靜態(tài)庫就打包好了,當(dāng)然是編譯器幫我們打包的,后續(xù)會更新如何自己親手打包一個庫(動靜態(tài)庫的知識)!
3.建立一個c++項目(TestStacklib) 引入c項目中的頭文件
??注意:這里的引入頭文件的路徑可以是相對路徑 其中…是代表的上級目錄 只需找到自己創(chuàng)建的動態(tài)庫的頭文件的路徑并在新建的c++項目中包含即可
本文中的test.cpp是一段關(guān)于括號匹配的算法代碼 可以用建的靜態(tài)庫里的棧的特性來解決
bool isValid(const char* s) { const char* cur = s; stack stack; StackInit(&stack); while (*cur != '\0') { if (*cur == '(' || *cur == '{' || *cur == '[')//如果是左括號就進(jìn)棧 { StackPush(&stack, *cur); } else { if (StackEmpty(&stack))//考慮到開始是右括號,那么就是棧為空,就不可能有效,直接返回FALSE { return false; } char top = StackTop(&stack); if (*cur == ')' && top == '(' || *cur == '}' && top == '{' || *cur == ']' && top == '[') { StackPop(&stack); } else { return false; } } cur++; } if (StackEmpty(&stack))//有可能只有一個左括號,進(jìn)棧就沒了,有效還有判斷棧是否為空,為空才是有效括號 return true; else return false; } int main() { cout << isValid("{{))") << endl; cout << isValid("({})") << endl; return 0; }
4.設(shè)置附加庫和附屬關(guān)系
將靜態(tài)庫中的debug目錄的路徑復(fù)制到附加庫目錄中
到這里附加庫目錄的操作就完成了 接下來就是在輸入中設(shè)置依賴項了
??到此準(zhǔn)備工作就完成了 接下來有兩種方法可以實(shí)現(xiàn)c++項目調(diào)用c靜態(tài)庫
1.將stack_c.lib中的stack.c的后綴改成stack.cpp 即可
2.在c++項目中使用extern “C” 表示編譯的時候按照c的規(guī)則編譯鏈接(主要就是函數(shù)名修飾的規(guī)則用c的規(guī)則)因?yàn)閏++是兼容c的所以c++的編譯器可以這么干 反過來c是不可以兼容c++的 所以反過來是行不通的。
接著往下看:
??第一種方法:將Stack_c.lib中的stack.c 改名為 stack.cpp(使得其編譯鏈接的時候是按照c++的規(guī)則,這樣c++項目調(diào)c++規(guī)則生成的庫就可以理所當(dāng)然的調(diào)動了,但是這樣的方式似乎很不著調(diào),本來是c庫,但是硬是把里面的源文件的后綴改成了cpp 不太好)
然后運(yùn)行那段代碼就可以成功運(yùn)行了 證明調(diào)用靜態(tài)庫成功!
??第二種:利用extern "C"改變c++項目的編譯鏈接過程的規(guī)則由c++的規(guī)則變成c的規(guī)則,這樣再調(diào)用c的靜態(tài)庫也就可以實(shí)現(xiàn)了,而且不用像第一種方法一樣去改源文件的后綴(強(qiáng)盜行為)
格式:
extern "C" { #include"庫的頭文件路徑" }
之后就可以運(yùn)行成功 ,表示鏈接成功了!就不貼圖了 與上面的圖一樣
二、c項目如何調(diào)用c++的庫(靜態(tài)庫為例)
還是那句話,c++兼容c 要用c項目調(diào)用c++庫 那么就只能是讓c++ 的庫編譯的時候用c的規(guī)則來,那么該咋弄呢?
還是extern “C”
1.建立c++項目(Stack_cpp) 并且將棧的源文件和頭文件包含在該目錄 將其打包為cpp的靜態(tài)庫
??右擊項目名稱 點(diǎn)擊屬性 再更改配置類型為靜態(tài)庫類型
??之后點(diǎn)擊到項目的路徑 進(jìn)入debug目錄 看到生成了一個Stack_cpp.lib 就說明生成打包靜態(tài)庫成功了!
接下來就是用extern "C"結(jié)合條件編譯來使得c++項目中的代碼按照c的規(guī)則來編譯鏈接 但是c項目要包含c++靜態(tài)庫的頭文件 那么就會在預(yù)處理的時候頭文件展開 那么c項目中就也會有 extern “C” 這是不可以的 只有c++才可以識別extern “C” c是識別不了的 會報錯?。?!
那么如何解決 ? 條件編譯這個時候就派上大用處了
??c++ 的文件中天然包含 __cplusplus 標(biāo)識符 而c是沒有的 可以以此為入口點(diǎn) 通過條件編譯使得extern “C” 在c++項目中展開 但是在c項目中不展開 就將問題解決了
下面還有一個簡化版的條件編譯
//簡化版 #ifdef __cplusplus extern "C" { #endif void StackInit(stack* pst); void StackDestory(stack* pst); void StackPush(stack* pst,STDataType x); void StackPop(stack* pst); bool StackEmpty(stack* pst); int StackSize(stack* pst); STDataType StackTop(stack* pst); #ifdef __cplusplus } #endif
之后就是 建立c項目 然后 建立test.c 拷貝那段關(guān)于括號匹配的代碼到其中 包含靜態(tài)庫的頭文件 添加打包的cpp動態(tài)庫到附加庫目錄 設(shè)置依賴項 通過調(diào)用cpp靜態(tài)庫里的棧的函數(shù)解決 運(yùn)行成功就說明c項目鏈接c++的靜態(tài)庫成功
2.建立c項目
3.包含靜態(tài)庫的頭文件
4 .添加打包的cpp動態(tài)庫到附加庫目錄 設(shè)置依賴項
然后就大功告成了 ,如果沒有差錯就可以直接運(yùn)行成功了。
??這里需要注意的是 要記得使用靜態(tài)庫前完成了準(zhǔn)備工作后一定要生成解決方案后再在來調(diào)用庫!
總結(jié)
到此這篇關(guān)于c/c++靜態(tài)庫之間相互調(diào)用的文章就介紹到這了,更多相關(guān)c/c++靜態(tài)庫間相互調(diào)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用C++進(jìn)行Cocos2d-x游戲開發(fā)入門過程中的要點(diǎn)解析
這篇文章主要介紹了使用C++進(jìn)行Cocos2d-x游戲開發(fā)入門過程中的要點(diǎn)解析,主要針對畫面變化以及觸摸響應(yīng)方面,需要的朋友可以參考下2015-12-12C語言實(shí)現(xiàn)簡易學(xué)生管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)簡易學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-06-06