2012-11-07 48 views
2

我已經編寫了一個基於其他幾個庫的C++共享庫。 現在,當使用庫時,我得到了很多關於'foreign'庫函數的未定義參考。編譯和鏈接工作正常,如果我明確地將'外部'庫添加到g ++命令。有沒有辦法解決這個問題,以便圖書館用戶不必手動鏈接到「外國」圖書館?共享庫中的外部庫

感謝您的幫助。

回答

1

如果您不希望共享庫的用戶必須聲明庫的所有鏈接時依賴關係,則可以在構建共享庫本身時通知鏈接器已經存在這些依賴關係。

,在Makefile中,這應該是這樣的:

mylib.so: 
    g++ -o mylib.so $OBJS -llib1 -llib2 -llib3 

隨後的mylib.so用戶並不需要指定lib1lib2lib3,但他們仍然需要可(在正確的版本)以使程序能夠運行。

0

您應該從發佈(導出)界面中排除所有外部數據類型和函數。這意味着,對於GCC,您可以使用-fvisibility=hidden來隱藏所有實施細節,因此,僅導出零件與attribute ((dllexport)。 Pimpl成語(aka Opaque pointer)可以幫助您從已發佈的頭文件中刪除依賴項。下面 簡單的例子:

#include<memory>  

#if EXPORT_DLL 
    #define DLL_PREFIX __attribute__ ((dllexport)) 
#else 
    #define DLL_PREFIX __attribute__ ((dllimport)) 
#endif 

class XImpl; 

class DLL_PREFIX X { 
//... 
private: 
    std::unique_ptr<XImpl> impl_; 
} 

定義並實現XImpl在另一頭/來源,僅此而已。沒有來自其他庫的鏈接依賴關係,只有你自己。但運行時依賴依然存在!

+0

感謝您的回覆,但我不明白這一點。假設我的庫的接口類是iface.hpp,並且實現位於iface.cpp中(在此文件中調用外部庫)。我將如何實施您的解決方案? – user1801173

+0

您的iface.hpp將包含'X'定義和'XImpl'的前向聲明(正如我提到的erarlier),iface.cpp可能包含'XImpl'定義或者包含外部頭文件,因此您可以使用init和'impl_'字段並通過它轉發所有方法。例如,如果你的X包含了一些'void f()'的方法,那麼你應該向XImpl中添加類似的方法,並在iface.cpp中調用它,同時從接口類實現'f()'來做實際的工作。 –

+0

好吧,所以我寫了一個新類將所有調用轉發給iface類。但是iface中的一些函數調用具有由外語提供的類型的參數。因此,我將不得不包含相關的標題。然後我在同一點? – user1801173