【问题标题】:g++ cannot find symbols when linkingg ++链接时找不到符号
【发布时间】:2012-06-22 11:35:12
【问题描述】:

好的,这可能是非常基本的,但我找不到问题。我正在尝试使用 -lyajl 将我的 C++ 程序与 C 共享库(以 YAJL 命名)链接;链接器似乎找到了它(它不会为此抱怨)但找不到我在代码中使用的符号:

$> g++ test.c -lyajl

Undefined symbols for architecture x86_64:
  "yajl_tree_parse(char const*, char*, unsigned long)", referenced from:
      _main in ccEqsAaJ.o
  "yajl_tree_get(yajl_val_s*, char const**, yajl_type)", referenced from:
      _main in ccEqsAaJ.o
  "yajl_tree_free(yajl_val_s*)", referenced from:
      _main in ccEqsAaJ.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
$>

我制作了一个极简的 test.c 文件来隔离行为。好吧,非常奇怪的是 gcc 似乎与代码完全一致(顺便说一下,test.c 只是 C 代码,这里没有 C++ 功能):

$> gcc test.c -lyajl
$>

gcc 在做什么,而 g++ 似乎无法做到这一点?

【问题讨论】:

    标签: gcc linker g++


    【解决方案1】:

    会不会是 libyajl.so 中的符号是 C 链接,但是您的代码(或您正在使用的头文件)没有声明它们 extern "C"?在这种情况下,将代码编译为 C++ 会导致目标文件中出现 name-mangled symbols,这与库中的(C 链接,未损坏)符号不匹配。

    解决方案是在头文件中编写如下内容:

    #ifdef __cplusplus
    // "__cplusplus" is defined whenever it's a C++ compiler,
    // not a C compiler, that is doing the compiling.
    extern "C" {
    #endif
    
    // Exchange "void" with the real return type for these functions
    void yajl_tree_parse(char const*, char*, unsigned long);
    void yajl_tree_get(yajl_val_s*, char const**, yajl_type);
    void yajl_tree_free(yajl_val_s*);
    
    #ifdef __cplusplus
    }
    #endif
    

    【讨论】:

      【解决方案2】:

      如果extern "C" 没有修复它,试试这个。

      我在尝试链接静态库 libyajl_s.a 时遇到了同样的问题。 可以通过将 yajl 源代码编译到可执行文件中来解决该问题, 但我真的需要静态库。 在仔细检查 yajl 源代码后,您会看到源代码正在两个单独的文件夹中寻找标题,例如

      #include <api/yajl_tree.h>
      #include <api/yajl_parse.h>
      #include "yajl_parser.h"

      链接器似乎将 yajl_tree_parse、yajl_tree_get 和 yajl_tree_free 解析为它们在 yajl_tree.h 中的原型,而不是它们在 yajl_tree.c 中的定义。换句话说,它们在生成的库中仍未定义。

      解决方案是将 api 文件夹中的所有标头移动到 src 文件夹中,并删除对<api/...> 的所有引用。然后链接器正确地选择了 yajl_tree_xxx 函数定义。

      【讨论】:

      • 谢谢,我也去看看。
      猜你喜欢
      • 2011-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-27
      • 1970-01-01
      • 2017-11-04
      • 1970-01-01
      相关资源
      最近更新 更多