如果此类是多态的,我发现类名不能隐藏在共享库中.例如,
// example.cpp
#include <stdio.h>
#include <string.h>
// #define virtual
class Base
{
public:
virtual const char* whatiam()
{
return "Papa";
}
};
class Child : public Base
{
public:
virtual const char* whatiam()
{
return "Son";
}
};
const char* whatiam(Base* obj)
{
return obj->whatiam();
}
__attribute__((visibility("default"))) const char* TheAPI(int n)
{
static char buf[64];
Child t;
sprintf(buf, "I'm %s.", whatiam(&t));
return buf;
}
Run Code Online (Sandbox Code Playgroud)
我在Linux上用这样的gcc构建一个共享库
$ g++ -fPIC -shared -fvisibility=hidden ../example.cpp -o libexample.so
$ strip -R .comment -R .note libexample.so
Run Code Online (Sandbox Code Playgroud)
然后我打开libexample.so在Emacs的一个正常的文件和搜索,类名Base和Child将被发现.
如果我取消注释语句// #define virtual是#define virtual,也就是化妆Base和Child不虚方法,我发现类名Base和Child不会在共享库中找到.
剂量类名是否由编译器存储在类vtable中?还是其他一些原因造成了这个问题?
如果此类是多态的,我发现类名不能隐藏在共享库中.
不清楚你指的是什么样的隐藏.
从链接器符号可见性角度看,隐藏了所有具有内部链接的名 类根本没有链接,函数和变量可以:
$ nm -C libexample.so
nm: libexample.so: no symbols
$ nm -D -C libexample.so
0000000000201030 B __bss_start
w __cxa_finalize
0000000000201030 D _edata
00000000002010a0 B _end
0000000000000944 T _fini
w __gmon_start__
0000000000000728 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
w _Jv_RegisterClasses
U sprintf
0000000000000899 T TheAPI(int)
U vtable for __cxxabiv1::__class_type_info
U vtable for __cxxabiv1::__si_class_type_info
$ strings libexample.so | c++filt
__gmon_start__
_init
_fini
_ITM_deregisterTMCloneTable
_ITM_registerTMCloneTable
__cxa_finalize
_Jv_RegisterClasses
TheAPI(int)
sprintf
vtable for __cxxabiv1::__si_class_type_info
vtable for __cxxabiv1::__class_type_info
libstdc++.so.6
libm.so.6
libgcc_s.so.1
libc.so.6
_edata
__bss_start
_end
CXXABI_1.3
GLIBC_2.2.5
fffff.
Papa
I'm %s.
5Child
4Base
;*3$"
Run Code Online (Sandbox Code Playgroud)
那些字符串5Child和4Basetypeinfo返回typeid():
typeinfo name for Child:
.string "5Child"
.hidden typeinfo for Child
.weak typeinfo for Child
.section .data.rel.ro._ZTI5Child,"awG",@progbits,typeinfo for Child,comdat
.align 16
.type typeinfo for Child, @object
.size typeinfo for Child, 24
typeinfo name for Base:
.string "4Base"
.hidden typeinfo for Base
.weak typeinfo for Base
.section .data.rel.ro._ZTI4Base,"awG",@progbits,typeinfo for Base,comdat
.align 16
.type typeinfo for Base, @object
.size typeinfo for Base, 16
Run Code Online (Sandbox Code Playgroud)
您可以使用-fno-rtti编译器开关禁用typeinfo :
-fno-rtti
Disable generation of information about every class with virtual
functions for use by the C++ run-time type identification features
(dynamic_cast and typeid). If you don't use those parts of the
language, you can save some space by using this flag. Note that
exception handling uses the same information, but G++ generates it
as needed. The dynamic_cast operator can still be used for casts
that do not require run-time type information, i.e. casts to "void
*" or to unambiguous base classes.
Run Code Online (Sandbox Code Playgroud)