假设我正在编写一个C ++库,它必须导出一个变量,一个数据结构,例如,ExpData
。因此,链接到我的libray的程序可以访问此变量(有一个公共标题将其定义为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 ++方面是否可能?
P.S。:我知道我不应该依赖于依赖于实现的细节,比如名称修改和C ++类内部数据,但只考虑我的库将在非常特定的环境中运行。
修改
我可以通过将--defsym ExpData=_ZTV12InternalType
传递给链接器来解决我的问题。但是,我不想将实现细节附加到外部资源。假设我决定将类'vtable映射为名为InternalTypeVTable
的C结构。因此,我可以将ExpData
声明为InternalTypeVTable ExpData;
。如果我只需要更改源文件,而不是makefile和链接器脚本,那就太棒了。
答案 0 :(得分:4)
GCC的__attribute__ ((alias()))
正是我需要的原因。
如果我宣布ExpData
喜欢:
void *ExpData[0] __attribute__ ((alias("_ZTV12InternalType")));
在我的库的源文件中,我得到以下汇编代码:
.globl ExpData
ExpData = _ZTV12InternalType
因此,导出的符号ExpData
引用的内存地址与_ZTV12InternalType
相同。