手动解析C++符号是否可能?

3
我正在遇到像这样的一些错误:
dyld: lazy symbol binding failed: Symbol not found: __ZN2nm8RationalIxEC1ERKNS_10RubyObjectE
  Referenced from: /Users/jwoods/Projects/nmatrix/lib/nmatrix.bundle
  Expected in: flat namespace

dyld: Symbol not found: __ZN2nm8RationalIxEC1ERKNS_10RubyObjectE
  Referenced from: /Users/jwoods/Projects/nmatrix/lib/nmatrix.bundle
  Expected in: flat namespace

然后对于__ZN2nm7ComplexIfEC1ERKNS_10RubyObjectE也是同样的处理。

不幸的是,c++filt似乎不想解开这些符号。当我尝试在c++filtjs在线界面中输入它们时,我得到了“不是一个混淆的C++符号”的提示。

我对错误信息有点困惑,因为c++filtjs给出的示例是_ZN9wikipedia7article8wikilinkC1ERKSs,表示wikipedia::article::wikilink::wikilink(std::string const&)。我看到几种模式,其中包括ZN#78用于::,以及C1ERK用于我猜测是某种构造函数的传递引用。

我猜它抱怨缺少我的class Rational的一个构造函数,例如Rational::Rational(RubyObject const&)。但是,Rational是一个模板,因此了解缺少哪个版本会很有帮助。

但问题是如何手动解开混淆的符号。 =)


5
可能需要从混淆名称的前面移除一个下划线。请注意不要改变原意,使语言更加通俗易懂。 - Shafik Yaghmour
2
nm::Complex::Complex(nm::RubyObject const&) 是第一个,nm::Rational::Rational(nm::RubyObject const&) 是第二个。您需要从名称修饰中删除第一个下划线。 - Rapptz
2
完全可以手动完成。但是,您需要了解名称修饰规则,这些规则因编译器而异...删除第一个下划线(有两个),它很可能会起作用。 - Mats Petersson
啊!谢谢,伙计们。这很有帮助。不是直接相关于这个问题:我知道如何显式编译特定的模板类,例如Rational<int>,但是如何显式编译特定的模板类构造函数呢? - Translunar
@mohawkjohn:最直接的方法是创建一个类的实例,使用你想要的构造函数。大多数编译器不会生成从模板中永远不使用的代码。一旦编译器看到你实际上在使用构造函数,它就会将其包含在它生成的代码中(尽管可能会进行内联)。 - cHao
1
你尝试过使用c++filt开关进行调试吗?有时候传递c++filt -t -n以不忽略下划线可以解析名称。 - greatwolf
1个回答

6
这个符号看起来像是clang或gcc生成的。这两个编译器都使用基于Itanium ABI的ABI。该文档包括一个关于解构的部分,描述了如何构造外部符号。如果您内化相应的规则,就应该能够解构名称。
我无法在原始网站上找到该文档,而且我不知道官方文档存放在哪里。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接