当前位置: 技术问答>linux和unix
[请教]关于共享库函数导出问题
来源: 互联网 发布时间:2015-11-18
本文导语: 本人对linux开发不熟悉,请大家不吝赐教。 在一个动态(共享)库中,有部分函数是只在内部使用,因此不能让用户看到这些接口。 在window下,开发标准dll时,可以使用MS提供的扩展语法dllexport将dll中的接口导出。 ...
本人对linux开发不熟悉,请大家不吝赐教。
在一个动态(共享)库中,有部分函数是只在内部使用,因此不能让用户看到这些接口。
在window下,开发标准dll时,可以使用MS提供的扩展语法dllexport将dll中的接口导出。
没有dllimport声明的函数就无法被外部使用。
但在linux上,生成的共享库(.so)如何能做到同样的效果? 目前我发现生成的.so中,nm可以看到所有的函数。
请指教!谢谢!
在一个动态(共享)库中,有部分函数是只在内部使用,因此不能让用户看到这些接口。
在window下,开发标准dll时,可以使用MS提供的扩展语法dllexport将dll中的接口导出。
没有dllimport声明的函数就无法被外部使用。
但在linux上,生成的共享库(.so)如何能做到同样的效果? 目前我发现生成的.so中,nm可以看到所有的函数。
请指教!谢谢!
|
对于内联函数的展开,每个编译器的实现略有不同,的确,如果内联函数过长,会被编译器当作普通函数来产生目标文件,宏与内联会让产生的代码膨张!!!!
对于static的限制,不仅作用于编译期,而且还会作用于连接阶段,目标文件中会有一个符号段,这里会对每个比如全局函数,全局变量,外部函数,外部变量等,在连接时会用到这种信息,如果你的一个函数由static关键字修饰,在连接时,若外部需要这个函数,连接时会报错,如果两个库中都有同一个全局函数名称,连接时根据搜索路径,如果先找到一个库中的相应函数,就会停止查找,因此就忽略了第二个库的函数,这种不好之处由C++中的命名空间进行解决的,当然,用户在使用你提供的库时,可以突破这种static的限制,就是修改目标文件的符号表,把static类型修改成全局类型,这样就让连接器认为是真的可导出的全局变量。若不相信,大家可以写代码进行测试
再说一下strip,在LINUX下通过strip的帮助看到以下信息:
[root@localhost root]# strip --help
Usage: strip in-file(s)
Removes symbols and sections from files
The options are:
-I --input-target= Assume input file is in format
-O --output-target= Create an output file in format
-F --target= Set both input and output format to -p --preserve-dates Copy modified/access timestamps to the output -R --remove-section= Remove section from the output
-s --strip-all Remove all symbol and relocation information
-g -S -d --strip-debug Remove all debugging symbols
--strip-unneeded Remove all symbols not needed by relocations
-N --strip-symbol= Do not copy symbol
-K --keep-symbol= Only copy symbol
-x --discard-all Remove all non-global symbols
-X --discard-locals Remove any compiler-generated symbols
-v --verbose List all object files modified
-V --version Display this program's version number
-h --help Display this output
-o Place stripped output into
大家注意-x.-X选项,这就是可以去掉某些符号声明,从而让nm看不到你想要隐藏的信息,也让用户看不到相应信息,还有-K选项,它可以用于伪装,给用户造成假象,其原理也是通过修改符号表来实现的!!!
结论:如果用户想要别人的程序不连接你的某些函数,用static关键字已足够,如果你想要隐葳函数名称,推荐你使用strip -x或者strip -X,但这种方法也不起根本性的作用,如果人家知道你内部的函数,完全可以再修改你的目标文件的符号表来重建相关函数声明,从而可以让用户程序连接你的代码。当然,没有用户会这样去做的!!!最彻底的办法莫过于将你的函数用宏的方式直接就地展开,这样用户就没有任何办法使用你的函数了!!!!!当然这样的后果就是造成代码膨胀,关键是LZ的需求是什么!!!!!
对于static的限制,不仅作用于编译期,而且还会作用于连接阶段,目标文件中会有一个符号段,这里会对每个比如全局函数,全局变量,外部函数,外部变量等,在连接时会用到这种信息,如果你的一个函数由static关键字修饰,在连接时,若外部需要这个函数,连接时会报错,如果两个库中都有同一个全局函数名称,连接时根据搜索路径,如果先找到一个库中的相应函数,就会停止查找,因此就忽略了第二个库的函数,这种不好之处由C++中的命名空间进行解决的,当然,用户在使用你提供的库时,可以突破这种static的限制,就是修改目标文件的符号表,把static类型修改成全局类型,这样就让连接器认为是真的可导出的全局变量。若不相信,大家可以写代码进行测试
再说一下strip,在LINUX下通过strip的帮助看到以下信息:
[root@localhost root]# strip --help
Usage: strip in-file(s)
Removes symbols and sections from files
The options are:
-I --input-target= Assume input file is in format
-O --output-target= Create an output file in format
-F --target= Set both input and output format to -p --preserve-dates Copy modified/access timestamps to the output -R --remove-section= Remove section from the output
-s --strip-all Remove all symbol and relocation information
-g -S -d --strip-debug Remove all debugging symbols
--strip-unneeded Remove all symbols not needed by relocations
-N --strip-symbol= Do not copy symbol
-K --keep-symbol= Only copy symbol
-x --discard-all Remove all non-global symbols
-X --discard-locals Remove any compiler-generated symbols
-v --verbose List all object files modified
-V --version Display this program's version number
-h --help Display this output
-o Place stripped output into
大家注意-x.-X选项,这就是可以去掉某些符号声明,从而让nm看不到你想要隐藏的信息,也让用户看不到相应信息,还有-K选项,它可以用于伪装,给用户造成假象,其原理也是通过修改符号表来实现的!!!
结论:如果用户想要别人的程序不连接你的某些函数,用static关键字已足够,如果你想要隐葳函数名称,推荐你使用strip -x或者strip -X,但这种方法也不起根本性的作用,如果人家知道你内部的函数,完全可以再修改你的目标文件的符号表来重建相关函数声明,从而可以让用户程序连接你的代码。当然,没有用户会这样去做的!!!最彻底的办法莫过于将你的函数用宏的方式直接就地展开,这样用户就没有任何办法使用你的函数了!!!!!当然这样的后果就是造成代码膨胀,关键是LZ的需求是什么!!!!!
|
tb01412(tb)分析的非常好,赞一个:)
楼主的需求是不明确。
static在elf格式里被放在local符号区,只能在本模块内使用,可以起到屏蔽的作用,但如果是一个内部使用的公用函数,这样会导致所有使用该函数的代码不得不放在一个源文件里,从而引起整个代码的物理架构的混乱。
楼主的需求是不明确。
static在elf格式里被放在local符号区,只能在本模块内使用,可以起到屏蔽的作用,但如果是一个内部使用的公用函数,这样会导致所有使用该函数的代码不得不放在一个源文件里,从而引起整个代码的物理架构的混乱。
|
用宏定义来做限制,看到也不能用。
|
static限制