2011-02-25 75 views
3

我有很多靜態庫。一個是static_lib_a.a。我創建了一個動態庫dynamic_lib.so將它們放在一起。dynamic_cast在隱藏符號時失敗

在static_lib_a.a中,它使用xerces 3.1.1來分析xml。以下是在static_lib_a.a

xerces::DOMElement *pElementNode = dynamic_cast<xerces::DOMElement *>(pNode); 

代碼段的類型pNode的是的xerces ::的DOMNode。它被分配給xerces :: DOMElement的一個對象。這行代碼將會向下轉換。

爲了隱藏dynamic_lib.so中的static_lib_a.a的所有符號,我使用-fvisibility = hidden來構建這個靜態庫。我發現如果我添加 - fvisibility =隱藏,pElementNode將在運行時返回一個NULL指針。

gcc編譯器的版本是3.4.4。

有沒有人有過類似的問題?

+0

你的編譯器很舊。你有沒有嘗試使用新版本的gcc編譯你的代碼? – 2011-02-25 11:53:06

+0

我不能這樣做,因爲其他舊模塊是在gcc中構建的3.4.4 – 2011-02-25 12:58:12

回答

3

問題的根源在gcc wiki中標題爲「C++異常問題」一節中描述。確保你遵循那裏的「模糊鏈接」鏈接並閱讀關於虛擬表和typeinfo的章節。

這一切都適用於你的情況,因爲類xerces::DOMNodexerces::DOMElement不包含非純的非內聯虛函數(實際上這些類完全包含在頭文件中)。這意味着每個類的虛擬表都在包含其頭的每個對象文件中發出。

dynamic_cast正常工作所需的任一類的typeinfo符號都會在與虛擬表相同的對象中發出,即在每個包含其標頭的對象文件中發出。

當您用隱藏的可見性標記庫時,來自static_lib_a.a的對象中的xerces::DOMNodexerces::DOMElement的所有typeinfo符號都被標記爲隱藏。正如維基頁面指出的那樣,這確保鏈接器將其標記爲隱藏在dynamic_lib.so中,並且您的dynamic_cast將失敗。

+0

非常好,你添加了缺失的位。 – 2011-05-14 22:03:13

1

使用隱藏的可見性是確保您的庫僅通過指定的訪問點使用的好方法。如果你修改它,這是一個巨大的優勢,因爲你確切知道你的庫是如何在外部使用的,因此限制了你可能會破壞的內容。

這是一個非常類似於Windows的技術,使您可以declspec指定DLL的可訪問部分的一部分,除非您導入或導出時沒有聲明的輕微差異,因此您的庫可能會使「可見的「功能,而不是實現。

要回答你的問題,我認爲僅支持版本4以上的可見性。當然,我們在這裏用它來與這個

#if defined(__GNUC__) && __GNUC__ >= 4

當您使用隱藏的知名度,你需要哪些符號確實希望可見明確地規定。因此,你有這樣的:

__attribute__((visibility("default")))

你可能#定義更多的東西可讀,也許SO_EXPORT因而其中:

#define SO_EXPORT __attribute__((visibility("default")))

的定義類:

class SO_EXPORT MyAccessInterface;

以及類似的方法:

SO_EXPORT int doSomething(parameters);

實際上,我們也有一個隱藏的知名度類似宏(同上,但與「隱藏」,而不是「默認」)。因此,即使我們在整個項目中使用「默認」可見性,我們也可以隱藏一些實現細節。

#define SO_HIDDEN __attribute__((visibility("hidden")))

class SO_HIDDEN MyClassImpl;

0

dynamic_cast要求所屬類別節點派生類在基類,其與動態重定位完成的所屬類別節點指向。如果typeinfo節點的符號不可見,那麼包含派生類節點的模塊將擁有自己的副本,然後dynamic_cast將假定這些類來自不同的樹並且不允許轉換。

您需要向基類定義添加聲明默認可見性的屬性。

+0

xerces是在沒有「-fvisibility = hidden」的情況下構建的。每個呼叫者都應該看到每類xerces。 – 2011-02-25 12:54:36

+0

@Blanc Yang:這兩個類都完全包含在頭文件中,因此xerces上的構建選項在這裏無關緊要。查看我的答案瞭解更多詳情。 – Troubadour 2011-05-13 23:30:13

相關問題