xcode 4.6符号可见性

时间:2013-02-18 22:13:46

标签: xcode export visibility xcode4.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和class z的函数将被导出或显示给其他项目。

我构建了没有错误或警告的框架,然后将其复制/添加到cocoa应用程序进行测试。

我能够包含头文件,但我仍然可以访问所有类和函数。

我希望有人可以解释为什么或哪里出错或者之前遇到过这个问题?

问候

1 个答案:

答案 0 :(得分: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直接在你的代码中的符号)。因此,隐藏符号只是一种保障,以确保它在任何情况下都不能使用。