假设我正在编写一个C++库,该库必须导出一个变量,即一种称为ExpData的数据结构。因此,链接到我的libray的程序可以访问此变量(有一个公共(public) header 将其定义为extern void *ExpData[])。

但是,此数据结构在内部是C++类的vtable。该类的名称例如是InternalType。因此,查看生成的汇编代码后,我发现InternalType的vtable导出为_ZTV12InternalType

然后,我需要一种方法来使用与ExpData相同的地址解析我的库导出变量_ZTV12InternalType,以便在外部程序读取我的库的ExpData变量时,它实际上是在读取InternalType的vtable。

为了澄清起见,InternalType的vtable汇编代码为:

    .type   _ZTV12InternalType,@object # @_ZTV12InternalType
    .section    .data.rel.ro._ZTV12InternalType,"aGw",@progbits,_ZTV12InternalType,comdat
    .weak   _ZTV12InternalType
    .align  16
_ZTV12InternalType:
    .quad   0
    .quad   _ZTI12InternalType
    .quad   _ZN12InternalType8vMethodXEi
    .size   _ZTV12InternalType, 24

因此,我需要一种方法来实现这一目标(或其他具有相同效果的目标):
    .type   ExpData,@object
    .globl  ExpData

    .type   _ZTV12InternalType,@object
    .section    .data.rel.ro._ZTV12InternalType,"aGw",@progbits,_ZTV12InternalType,comdat
    .weak   _ZTV12InternalType
    .align  16
_ZTV12InternalType:
ExpData:
    .quad   0
    .quad   _ZTI12InternalType
    .quad   _ZN12InternalType8vMethodXEi
    .size   _ZTV12InternalType, 24

在C++方面有可能吗?

附注:我知道我不应该依赖于依赖于实现的细节,例如名称处理和C++类内部数据,而只是考虑我的库将在非常特定的环境中运行。

编辑

我可以通过将--defsym ExpData=_ZTV12InternalType传递给链接程序来解决我的问题。但是,我不想将实现细节附加到外部资源上。假设我决定将类的vtable映射为名为InternalTypeVTable的C结构。因此,我可以将ExpData声明为InternalTypeVTable ExpData;。如果只需要更改源文件,而不更改makefile和链接程序脚本,那将是很好的。

最佳答案

GCC的__attribute__ ((alias()))正是我需要的原因。

如果我像这样声明ExpData:

void *ExpData[0] __attribute__ ((alias("_ZTV12InternalType")));

在库的源文件中,我得到以下汇编代码:
    .globl  ExpData
ExpData = _ZTV12InternalType

因此,导出的符号ExpData_ZTV12InternalType引用相同的内存地址。

10-05 22:59