2013-02-18 76 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