动态链接库so文件中的函数名隐藏
动态链接库so⽂件中的函数名隐藏
在我们提供给别⼈使⽤的动态链接库so⽂件时,其内部实现函数的名称,特别是⼀些关键名称我们是不希望别⼈见到然后反向的,这时候⼀般有两种处理⽅式:⼀是把程序中关键词修改了再编译,⽐较蠢笨;⼆是通过编译的⽅式将字符隐
藏,gcc编译器提供了这个选项,即在编译选项中加⼊-fvisibility=hidden选项。
⽐如ndk⾥这样操作:LOCAL_CPPFLAGS +=-fvisibility=hidden。执⾏编译后,使⽤nm -D xxx.so命令或者readelf --symbols xxx.so即可查看so⽂件中符号列表,此时所有符号已经隐藏了,好像似乎⽬的达到了,但是引⽤此so⽂件时发现根本运⾏不起来,那么问题出哪⼉了?
其实,根据动态链接库调⽤原理可知,程序在显⽰或隐⽰调⽤so⽂件时,跟静态库⼀样是需要使⽤确定名称的函数的,⽽执⾏-fvisibility=hidden编译后,所有函数名称都被隐藏了,这时候程序当然运⾏不起来了。
那么正确的思路应该是暴露出要被调⽤的函数名称,⽽隐藏不被外部使⽤的其他符号即可,具体操作为:
在需要暴露(导出)的函数前增加属性__attribute__ ((visibility("default"))),例如,
__attribute__ ((visibility("default")))
void hello(void)
{
}
这样就把函数hello导出来了,⽽其他没有添加该属性的,就被-fvisibility=hidden给隐藏了,到此我们的⽬标就实现了。
当然,为了⽅便使⽤,可以把该选项⽤宏定义,写函数的时候就可以使⽤,⽐如:
#ifdef WIN32
# ifdef EXPORT
...
# else
....
# endif
# define DLL_LOCAL
显示隐藏文件
#else
# ifdef __GNU__
#  if (GCC_SUPPORTS_VISABLE == 1) /*defined by configure*/
#  ifdef EXPORT
#    define DLL_API __attribute__ ((visibility("default")))
#  else
#    define DLL_API __attribute__ ((visibility("default")))
#  endif
#  define DLL_LOCAL __attribute__ ((visibility("hidden")))
#  else
#  define DLL_API
#  define DLL_LOCAL
#  endif
# endif
#endif
这样可以在函数前添加相应的属性,DLL_API或DLL_LOCAL

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。