【发布时间】:2014-07-29 13:35:32
【问题描述】:
假设我正在编写一个 C++ 库,它必须导出一个变量、一个数据结构,例如,称为ExpData。因此,与我的库链接的程序可以访问此变量(有一个公共标头将其定义为extern void *ExpData[])。
但是,这个数据结构在内部是 C++ 类的 vtable。例如,类的名称是InternalType。于是,查看生成的汇编代码后,发现InternalType的vtable导出为_ZTV12InternalType。
然后,我需要一种方法来使我的库导出变量ExpData 解析为与_ZTV12InternalType 相同的地址,这样,当外部程序读取我的库的ExpData 变量时,它实际上正在读取@987654329 @的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;。如果我只需要更改源文件,而不是生成文件和链接器脚本,那就太好了。
【问题讨论】:
-
你不使用标题吗?
-
@ColeJohnson 是的,但是标头应该声明变量,而不是定义它。所以,我需要一种方法来将我的变量定义为编译器生成结构的入口点。
-
所以你想做一个粗略的反射形式就是我所看到的?你的问题对我来说并不完全清楚。
-
@ColeJohnson 这不完全是反射。它可以是任何编译器生成的数据,而不仅仅是 C++ 类。如果我有编译器生成的结构的符号名称,我需要一种将变量与其关联的方法。我需要用相同的地址解决它们。
-
您应该使用
ld链接器脚本在特定地址手动生成符号。