【问题标题】:Mangling names for templated functions in runtime - possible?在运行时修改模板函数的名称 - 可能吗?
【发布时间】:2016-01-19 22:53:46
【问题描述】:

假设我已经编写了一个foo<T> 函数(我有一个带有命名空间的完整签名),但现在不要介意);并假设没有其他函数重载它(在它所在的相关命名空间中)。现在让我们将自己置于运行时。假设我有字符串“foo”,对于某些类型MyType,我有typeid(MyType)(来自<memory> 标头)。

我能否以某种方式获得foo<MyType> 的符号name

这个问题的第二个版本:现在假设我将 foo 的完整签名作为字符串,而不仅仅是名称;并放弃关于没有重载的假设。

注意事项:

  • 不,我问的不是符号本身,只是名称。这将是另一个有趣的问题。
  • 依赖于来自共享库的 foo<T> 的答案是相关的,尽管我认为这对于符号 name 并不重要。
  • 我不关心这里的性能,我会做任何事情。帮帮我 Obi Wan,你是我最后的希望等等。所以,RTTI,用奇怪的标志编译,无论如何。
  • 平台相关的答案也很重要:GNU/Linux with kernel version >= 3.x , an x​​86_64 CPU , gcc >= 4.8 。

【问题讨论】:

  • 这对于 C 和 C++ 是一样的,除非你广泛使用 RTTI,据我所知,这是一个相当不常见的选择(都是由于负面的副作用而不是真正的全部)有帮助)。
  • @MarcusMüller:实际上,我看不出这有什么关系。
  • C 和 C++ 是非反射语言。没有信息在编译后调用您的方法/函数。
  • @MarcusMüller:我知道它们是非反射语言,否则我不会对符号之类的东西感兴趣,它们是在我们从语言代码变为编译形式之后存在的......

标签: c++ symbols name-mangling


【解决方案1】:

不,你不能。

要获得实例化函数模板的重整名称,在最简单的情况下,您需要以下信息:

  • 函数的完全限定名(你说你只有"foo",如果函数在命名空间中怎么办?)
  • 所有模板类型参数的类型(类型的重整名称​​可能就足够了,如果函数名称的重整方案直接嵌入类型名称;否则您需要完整的类型名称,可能会递归到该类型的所有模板参数中)。
  • 所有函数参数的类型(同样需要注意)。

这是假设您没有模板模板参数或非类型参数。当你拥有这些时,它会变得更加复杂,因为它可能需要整个表达式树的错位形式。它还假设您没有处理部分或完全显式特化,这更加复杂。最后假设您的函数由于特定于编译器的扩展而没有任何特殊修饰(例如,__stdcall 在 32 位 Windows 环境中)。哦,有些 ABI 也可能对函数的返回类型进行编码。

因为根据您的前提,您只有函数名称(不清楚它是否是完全限定的)和模板参数的 type_id 对象(可能作为损坏类型的来源名称,但不是在所有平台上),您没有足够的信息来重新创建损坏的名称。

这留下了从二进制文件中获取所有已编译符号列表的选项(如果有的话)并搜索最有可能的候选者,这当然容易出错。

【讨论】:

  • 我的意思是我确实有你列出的信息,我只是没有提供所有这些的例子。
  • @einpoklum 回复:第二版。不幸的是,作为字符串的函数的完整签名仍然不够,因为签名中类型的修改取决于类型的定义。 Typedef 被查看,类和枚举可能有不同的修饰。 (在 MS 编译器的情况下,structclass 触发不同的修改,这实际上不符合标准。)
猜你喜欢
  • 2018-07-09
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多