【问题标题】:Undefined reference error - rand未定义的引用错误 - rand
【发布时间】:2012-03-29 13:12:53
【问题描述】:

我正在创建一个命令行 C++ 测试应用程序(可执行文件),以便在我的根 Android 设备上运行。

可执行文件使用多个预构建的 C 库,其中一个使用“rand()”。在链接状态期间,我收到错误“undefined reference of 'rand'

为了检查路径是否设置正确,我尝试了以下方法但没有成功。

第一种方法:我在测试源中定义了 rand()。

我注意到我得到多个定义错误,第一个定义在 bionic/libc/include/stdlib.h 中

第二种方法:在我的测试应用程序中使用了 rand()

我注意到链接器在这里没有抱怨未定义的符号

第三种方法:取消归档并归档所有目标文件

发现我仍然得到未定义的引用错误。

当使用 'rand' 的 C 库被编译成使用 C 测试文件的可执行文件时,不会出现上述链接器错误。

我无法修改预构建的静态库,需要将该库与基于 C++ 的测试应用程序一起使用。

非常欢迎任何意见。

【问题讨论】:

  • 在我看来,图书馆希望 rand 返回 'int rand' 而不是 'unsigned int rand'。如果它是静态链接的,为什么要使用“hack”并编译/链接测试 C 文件?
  • rand 是标准 C 模块,在创建共享对象或可执行文件时被链接。提供给我的静态库使用 rand() 调用并且没有包含它的定义。
  • 我建议查看符号转储程序。我知道 rand() 是什么,并且我发现您的静态库可能是针对与您的 C 库使用的不同版本进行编译的。您可以通过多种方式清除此问题(提供您自己的 rand、为 C rand 提供“包装器”等),但最好的办法是检查符号转储。我也会引导你到stackoverflow.com/questions/4768180/rand-implementation

标签: android c++ c linker


【解决方案1】:

没有足够的积分来评论所以......

如果你查看仿生的 stdlib.h,你会看到 rand() 被定义为

静态 内联 int rand(void) { ... }

即函数的实际代码在头文件中。

这就是为什么你的第一种方法会给你一个多定义错误。

您的第二种方法因同样的原因而成功,并且(因为该函数是内联的)不会在目标文件中生成任何“外部”引用来导致搜索任何库。

接下来。您的 C++ 代码将链接到 libc 或 libstdc++(您需要检查)。您的预构建静态库显然是针对没有 rand() 内联实现的 stdlib.h 编译的。

您需要对静态文件执行 LDD(或 readelf)命令,然后查看它所查找的库在您的平台上不存在。很可能该库与仿生库同名,后者不导出 rand() 符号,因此加载器无法解析引用。

现在,至于解决这个问题……如果不能更改静态库,您至少可以重建它们吗?你的 C 测试文件是为 android 交叉编译的,还是原生的?

【讨论】:

    【解决方案2】:

    使用'android-ndk32-r10-windows-x86_64.zip',而不是'android-ndk64-r10-windows-x86_64.zip'

    APP_ABI := armeabi armeabi-v7a x86
    

    3 api是32位的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      相关资源
      最近更新 更多