.framework设置函数的可见性(__attribute__((visibility ("XXX"))))

.framework设置函数的可见性

visibility用于设置动态链接库中函数的可见性,将变量或函数设置为hidden,则该符号仅在本so中可见,在其他库中则不可见。

g++在编译时,可用参数-fvisibility指定所有符号的可见性(不加此参数时默认外部可见,参考man g++中-fvisibility部分);若需要对特定函数的可见性进行设置,需在代码中使用__attribute__设置visibility属性。

编写大型程序时,可用-fvisibility=hidden设置符号默认隐藏,针对特定变量和函数,在代码中使用 __attribute__ ((visibility("default"))) 令该符号外部可见,这种方法可用有效避免so之间的符号冲突。

当我们使用Xcode封装一个.framework的库时,我们可以使用-fvisibility=hidden 设置所有函数默认不可见,如下图所示:
图片1

当我们将库函数设置为默认不可见时,我们仍在外部调用库函数时会出现类似这样的错误:

ld:symbol(s) not found for architecture 'XXX'
clang:linker command failed with exit code 1(XXX)

这是因为我们在编译时已经将库函数设置为不可见了,所以.framework在生成的时候并没有将我们使用的函数设置为导出函数,在.framework的头文件中我们还能看到定义的库函数,但是并不能使用。
我们可以通过设置一个宏,在我们需要使用的参数前添加这个宏,那么我们就可以在外部调用这个参数了,宏如下所示:

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

然后在我们需要使用的地方添加这个宏:

FMap_EXPORT 
@interface FGLMapView : UIView
...
@end

扩展

visibility_type 的值如下所示:

  • default

    假定的符号可见性可通过其他选项进行更改。缺省可见性将覆盖此类更改。缺省可见性与外部链接对应。

  • hidden

    该符号不存放在动态符号表中,因此,其他可执行文件或共享库都无法直接引用它。使用函数指针可进行间接引用。

  • internal

    除非由特定于处理器的应用二进制接口 (psABI) 指定,否则,内部可见性意味着不允许从另一模块调用该函数。

  • protected

    该符号存放在动态符号表中,但定义模块内的引用将与局部符号绑定。也就是说,另一模块无法覆盖该符号。

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/victor_barnett/article/details/80316153
个人分类: iOS的知识点
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭