[英]How do I connect a C program to a C++ library without needing stdc++ to link them?
我試圖將一些代碼添加到需要使用C ++庫的更大的C項目中。
C ++庫提供了一個包裝器,它使用標記為extern“C”的函數,可以訪問庫的功能
//Some C++ library
//mywrapper.h
#ifdef __cplusplus
extern "C" {
#endif
void wrapperFunction1( int width );
void wrapperFunction1( int height);
#ifdef __cplusplus
} // extern "C"
#endif
這與g ++編譯沒有問題。
在制作C程序並包含mywrapper.h時,我不斷得到引用vtable和cxa_pure_virtual的鏈接器錯誤:
undefined reference to `vtable for __cxxabiv1::__class_type_info'
undefined reference to `__cxa_pure_virtual'
在測試中,這些錯誤消失了,並且在我添加stdc ++庫時允許程序編譯,但這不是大C項目的選項。 有沒有辦法編譯C程序來訪問沒有這些錯誤和沒有stdc ++的C ++庫? 並且錯誤的交易是指在C ++庫內部並且未在mywrapper.h中引用的模塊,那么為什么C程序甚至試圖引用它們呢?
C ++庫依賴於標准C ++庫(libstdc ++,鏈接器的-lstdc++
選項,如果通過g++
運行鏈接器則默認)。 這是事實。 沒有什么可以做的。 克服它。
該包裝頭並不是指那些符號,但在庫中的實際對象文件執行 。 因此需要定義它們,定義它們的方法是包含標准C ++庫。
請注意,如果包裝的庫本身是動態的,它將知道它的依賴性,並且您不必動態地指定針對libstdc ++的鏈接。
你包裝的C ++庫需要stdc ++,而不是你的包裝器。
您已經包裝了C ++函數,以便它們可以從C 調用 ,但它們仍然在內部使用依賴於C ++標准庫的庫。 如果您不提供stdc ++,那么您正在使用的庫將缺少其實現的一部分。 除非你重寫C ++庫,否則無法繞過它。
完全有效的不包括libstdc++
和一些警告。 根據您在C ++代碼中所做的操作(或者在這種情況下,您正在包裝的庫),它可能希望底層運行時提供某些功能:
__cxa_pure_virtual
如果您有未實現的純虛函數(例如,在純抽象類中) main()
和析構函數之后調用構造函數 這不僅發生在您不包含libstdc++
庫時,而且還發生在已刪除的庫自定義版本上。
例如,Rowley Crossworks for ARM(嵌入式系統的工具鏈)建議您自己編寫__cxa_pure_virtual
錯誤處理程序。
通常,C ++代碼需要一定程度的運行時支持來處理特定的C ++特性。 例如,有一個處理dynamic_cast<>()
的庫函數。 即使您不使用任何標准C ++庫,您也需要這種語言支持libray。 它通常包含在標准C ++庫中,但專門針對gcc,此庫可單獨使用。 也就是說,你可能會逃避不包括libstdc++
但你不會逃脫包括這個庫。 目前我無法知道它是如何被調用的。 我認為這是-lcxxabi
但我不確定。
好的,我做了更多的研究,我偶然發現了答案,我有兩個問題,首先是錯誤信息:
./lib.so: undefined reference to vtable for __cxxabiv1::__si_class_type_info'
./lib.so: undefined reference to `vtable for __cxxabiv1::__class_type_info'
這些與C ++的運行時類型信息或rtti有關。 使用“-fno-rtti”編譯庫消除了這些錯誤。
第二個問題是:
./lib.so: undefined reference to __cxa_pure_virtual'
這是因為C編譯器無法處理來自C ++的虛函數。 使用extern“C”創建存根函數消除了錯誤並允許項目編譯。
我還在確認庫是否正常工作,但這些更改似乎已經糾正了錯誤。
感謝大家的幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.