如果此类是多态的,我发现类名不能隐藏在共享库中。例如,
// 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;
}
我在Linux上使用像这样的gcc构建一个共享库
$ g++ -fPIC -shared -fvisibility=hidden ../example.cpp -o libexample.so
$ strip -R .comment -R .note libexample.so
然后我在Emacs中打开libexample.so
作为普通文件进行搜索,找到类名Base
和Child
。
如果我将语句// #define virtual
取消注释为#define virtual
,也就是说没有虚拟方法make Base
和Child
,我会找到类名{{1将无法在共享库中找到和Base
。
编辑时,类名称是否存储在类 vtable 中?或者其他一些原因导致了这个问题?
答案 0 :(得分:5)
如果此类是多态的,我发现类名不能隐藏在共享库中。
不清楚你所指的是什么样的隐藏。
从链接器符号可见性角度来看,隐藏了所有具有内部链接的名称。类根本没有链接,函数和变量都有:
$ 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$"
这些字符串5Child
和4Base
是typeid()
返回的typeinfo:
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
您可以使用-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.