2013-02-18 95 views
0

我有隱藏在xcode 4.6中的符號的輕微問題或誤解。我在網上到處搜索,找不到任何具有相同問題的帖子。xcode 4.6符號可見性

目前,我已經創建了一個框架項目包含這樣一個簡單的頭文件:

class Test 
{ 
public: 

    Test(){} 
    Test(){} 
}; 

int a(int n) {return n;} 

__attribute__((visibility("hidden"))) int b(int n) {return n;} 

__attribute__((visibility("default"))) int c(int n) {return n;} 

class X 
{ 
public: 
    virtual ~X(); 
}; 

class __attribute__((visibility("hidden"))) Y 
{ 
public: 
    virtual ~Y(); 
}; 

class __attribute__((visibility("default"))) Z 
{ 
public: 
    virtual ~Z(); 
}; 

X::~X() { } 
Y::~Y() { } 
Z::~Z() { } 

在項目設置中我已確保「符號默認是隱藏的」切換到YES,因此只有功能int c和類z將被導出或對其他項目可見。

我構建的框架沒有錯誤或警告,然後複製/添加到可可應用程序進行測試。

我能夠包含頭文件,但我仍然能夠訪問所有類和函數。

我希望有人能解釋我爲什麼或在哪裏出錯或者之前遇到過這個問題?

問候

回答

1

你的問題是,你正在申報中頭文件一切。這意味着即使這些符號沒有導出,當您將頭文件導入到另一個文件時,這些符號也會在導入頭文件的項目中重新創建,因此它們當然可以在此項目中使用。

我想通過一個更簡單的示例向您解釋這一點。假設你有兩個文件,MyLib.h和MyLib.c。

MyLib.h:

int add(int a, int b); 

MyLib.c:

int add(int a, int b) { return a + b }; 

如果現在就add一個hidden知名度和編譯所有的庫(MyLib),該庫將沒有任何符號爲add(因爲它是隱藏的)。因此,如果將MyLib.h包含到另一個文件中,請調用add函數,最後將該文件鏈接到MyLib,您將收到鏈接器錯誤,因爲鏈接器會抱怨它無法找到add的實現(它只有H文件的聲明)。

但是,如果你包的功能到包頭本身,所以MyLib.h是:

int add(int a, int b) { return a + b }; 

,你給add一個hidden知名度,圖書館也將沒有任何符號add,但是當你將標題包含到另一個文件中,該標題將在導入該文件的文件中爲add創建一個符號,因此當然,您將不會收到鏈接器錯誤並能夠呼叫add

導入H文件意味着將H文件的全部內容複製到已經找到導入指令的位置。現在想一想:如果您將問題中H文件的全部內容複製到包含它的文件的頂部,那麼當前聲明的所有符號在當前項目中都可見且可用。爲什麼他們不可見或可用?它們不在圖書館中,是的,但是它們在標題中,因此在編譯其他項目時會進行編譯。

應該不會在您的框架的任何公共頭文件中出現應該在當前項目之外不可見的符號(「隱藏」符號)。爲什麼你會宣佈頭文件中存在無法使用的符號?實際上,在大多數情況下,不公開頭文件中的符號已經足以防止人們使用它們。不導出它們的原因僅在於如果符號存在,即使它沒有被任何頭文件公開(因此,您只需編寫自己的頭文件或直接在您的頭文件中聲明它爲external符號碼)。所以隱藏符號只是保證它在任何情況下都不能使用。

+0

感謝梅克,當然,我是完全愚蠢的(腦筋被炸,但沒有藉口)。我想我對[這個蘋果頁面](https://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/CppRuntimeEnv/Articles/SymbolVisibility.html)感到困惑,因爲它展示了一個例子,我雖然是在一個頭文件中,或者正在演示如何放置__attribute __((visibility(「default」)))或其他。 那麼如果內聯函數int add例如它會隱藏正確? – themadme 2013-02-19 13:46:58

+0

如果您聲明瞭函數'inline',但仍將其放入標題中,則無論標題包含在何處,它都將仍然可見。如果你想讓一個函數在你的庫之外不可見,那麼聲明它爲'hidden',並確保它不出現在你的框架包的任何頭文件中。只需使用私有H文件,該文件僅對框架文件可見,但不能複製到框架束,因此對於鏈接到您的框架的項目不可見。 – Mecki 2013-02-19 14:00:10

+0

再次感謝你的智慧麥基。現在我無法等待回家,並繼續將我的Windows項目轉換爲Mac,並希望Linux。 再次感謝。 – themadme 2013-02-19 14:16:56