【问题标题】:C++ name mangling in a soC++ 名称修饰在一个 so
【发布时间】:2013-02-26 14:21:52
【问题描述】:

这就是我所做的:

我从

更改了一个 .h 文件
SomeObj* getCacheObj( int i = 0 );

SomeObj* getCacheObj( int i );
SomeObj* getCacheObj();

我重新编译了代码(没有问题),更改到 somelib.so(许多 so 文件之一)。然后我用这个替换了设备上的旧so,加载so时出现以下错误: undefined symbol: _ZN13KeypathHelper11getCacheObjEv

现在奇怪的是,有人告诉我这个类只在这个 so 文件中使用(我怎样才能确定?)。我没有那么有经验,也不知道如何调查。欢迎提出任何建议。

更新

这个特殊问题是因为另一个so文件正在使用KeypathHelper类而我只替换了包含它的那个。我发现哪些其他需要更新的方法是对 KeypathHelper 进行 grep。

【问题讨论】:

  • 你所做的一切都在改变 .h 吗? .cpp 文件没有变化?
  • 我当然为新方法添加了一个实现

标签: c++ dynamic-linking shared-libraries name-mangling


【解决方案1】:

_ZN13KeypathHelper11getCacheObjEv 符号是 KeypathHelper::getCacheObj() 的错位名称(例如,您可以使用 c++filt 轻松翻译)。鉴于您只添加了一个方法并且加载共享对象的任何内容都找不到它让我认为您没有更新共享对象或忘记为KeypathHelper::getCacheObj() 提供定义(换句话说 - 实现该方法) .

为了进行调查,您必须查看无法解析符号的原因。通常,开发人员对此有所了解。比如说,如果二进制 XXX 由于未解析的符号而无法加载库 YYY,那么 XXX 正在使用它,并且它似乎不在 YYY 中(或其他任何地方)。如果没有意义,可以求助于阅读ld.so (8) manual page 并使用可用的方法(如定义LD_DEBUG)调试动态链接器。

另外,@PlasmaHH 提出了一个非常好的问题。如果您所做的唯一更改是对头文件的更改,那么您必须知道具有参数默认值的单个函数/方法与两个函数/方法(一个有参数而一个没有参数)是不同的。

关于如何确保共享对象中的符号不​​在外部使用的第二个问题 - 您必须更改符号的可见性,以便外部的任何人都无法链接/解析/使用该符号。例如,请参阅GCC Visibility

希望对您有所帮助。祝你好运!

【讨论】:

    猜你喜欢
    • 2017-11-28
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 2010-12-18
    • 2011-02-25
    • 1970-01-01
    • 2011-09-25
    • 2011-05-27
    相关资源
    最近更新 更多