簡體   English   中英

混合C / C ++代碼會在共享庫中產生“未定義符號”

[英]Mixing C/C++ code yields “undefined symbol” with shared library

這個問題使我困擾了一個星期,所以我認為可能終於是時候向你們尋求幫助了。 簡而言之,這是一個故事:

我們正在內部使用Qt / C ++開發嵌入式服務器。 這是一個非常簡單的服務器,它處理客戶端請求並通過dlopen()/ dlsym()調用加載適當的功能,以執行特定於供應商的操作。 這意味着供應商將簡單地以C格式向我們提供一個.so文件,其功能(對我們而言是透明的)與我們定義的方式相同。 這將用C語言編寫,因為它需要做很多底層工作,而我們的服務器則在Qt中使用,因為我們計划最終擁有一個前端。

這是一些偽代碼:

在我們的main.cpp文件中(該文件以C語言編寫,但是使用Qt mkspec中定義的g ++編譯器,並使用-ldl和-rdynamic進行編譯以導出所有符號):

  • dlopen()vendor.so文件(同時使用RTLD_NOW和RTLD_LAZY嘗試)
  • dlsym()vendor.so init()方法(這將調用供應商的init方法,該方法將通過我們代碼內的setter方法設置此“供應商插件”的名稱/屬性,將其稱為plugin_set_name(args ...))

在共享頭文件(shared.h)中(兩個代碼庫都將使用此文件;我們將具有完整的結構定義,供應商將僅具有setter / getters的原型):

  • extern“ C” int plugin_set_name(args ...)

在供應商main.c文件中(使用gcc,-fPIC和-shared編譯)

  • 如上所述的init()函數的實現

因此從本質上講,發生的事情是C ++代碼將使用dl調用從C .so庫中加載init()函數,然后C .so庫將調用C ++代碼中定義的函數(在在這種情況下為plugin_set_name)。 這有可能嗎? 由於它們是彼此獨立且使用不同的編譯器(gcc與g ++)進行編譯的,因此兩者之間不會相互鏈接。

我遇到的錯誤是在運行時:“未定義的符號:plugin_set_name”(因此它可以在庫的init()方法中找到並獲取它)。 當我使用gcc和直接C代碼執行所有操作時,它可以完美地工作,所以我知道這不是代碼,而是混合C / C ++的東西。 我也理解使用extern“ C”防止名稱修飾,並使用nm / readelf確定沒有任何類型的修飾。 有任何想法嗎? 最好的方法是什么?

不知何故,這在今天神奇地起作用了。 我無法解釋。 我只是在共享頭周圍有extern“ C”聲明,所以在shared.h中:

#ifdef __cplusplus
extern "C" {
#endif

plugin_set_name(args...)
other_shared_functions

#ifdef __cplusplus
}
#endif

我一直都這樣。 無論哪種情況,它現在都可以用C編譯供應商插件,而Qt和C ++編譯服務器。 我認為問題在於所有外部元素的放置位置以及g ++鏈接標志(其中rdynamic至關重要)的組合。 謝謝。 只是將其放在此處,以防其他人遇到相同的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM