【问题标题】:Android NDK: libc++ support for hard-floatAndroid NDK:libc++ 支持硬浮点
【发布时间】:2017-04-17 05:16:50
【问题描述】:

我在编译一个使用多个自定义 c++ 库的小型 Java 程序时遇到了问题。所有库都以 armeabi-v7a 为目标,并使用硬浮点支持进行编译(mfloat-abi=hard -mfpu=neon -mhard-float -D_NDK_MATH_NO_SOFTFP=1)。我有几个其他 cpp 文件是 Java/Android 项目的一部分;这些也是使用上述设置编译的,我链接到 libm_hard.a(而不是 libm.a)

当我运行程序时,cpp 文件(不是自定义库)中的浮点数出现了奇怪的行为,类似于arm cortex a9 cross compiling strange floating point behaviour。合法的浮点值(在代码中,通过调试器检查)在 stdout 或 fstream 上打印为非常小的值(例如 1.47895e-309)。

  std::ofstream os;
  os.open(filename, std::ios::out);

  double x = 0.34343;
  double y = log(0.1);

  os << x << "\t" << y << endl;

  os.close();

这似乎是因为 libc++ 库不是为硬浮点编译的;我尝试了 libc++ 的静态和共享版本,我得到了相同的行为。我还通过 readelf 检查了它们,看来它们不是为硬浮点编译的(没有提到 VPF 寄存器)。我无法在 NDK 中找到为硬浮点编译的 libc++(静态或共享)版本。

  • Android SDK:21(也尝试了 23)
  • NDK:14.1.3816874
  • Android Studio:2.3.1

我不能(轻易地)将上游库从硬浮点更改为软浮点;有些专注于重矩阵处理并针对硬浮点进行了优化。而且,据我了解,我不能混合使用 softfp 和 hard...

除了为硬浮点重新编译 libc++ 之外,我还有其他选择吗? (我知道不久前谷歌放弃了对硬 abi 的支持,它一定有相应的 libc++ 库)

编辑:添加示例代码

【问题讨论】:

  • 发布您用来输出浮点值的代码。如果问题出在libc++ 库,则可能有一种方法可以将float 值转换为可以输出的字符串。也许 C 风格的 printf() 或类似的也可以。
  • 谢谢,我会试试的,虽然我认为这可能是同一个问题,只是推迟到 libc 而不是 libc++。此外,在 3rd 方库中可能有其他地方(一些我无法控制)会出现导致问题的 libc++ 依赖项。
  • @AndrewHenle 您的建议有效(至少对于处理文本 io 和浮点数),再次感谢。我仍然对其他人使用硬浮点标志编译的 libc++ 进行链接感到好奇。

标签: android c++ android-ndk java-native-interface


【解决方案1】:

硬浮点 ABI 支持已从 r12 中的 NDK 中删除:https://android.googlesource.com/platform/ndk/+/master/docs/HardFloatAbi.md

停止使用 libm_hard 应该没问题(不删除这是 r15 中修复的疏忽,抱歉造成混淆!)。

请务必注意,非硬浮点 ABI 仍然使用浮点指令。唯一的区别是传递 ABI 的函数参数。

【讨论】:

  • 谢谢。只是为了确保我理解您的建议:我不应该与 libm_hard 链接,并且还应该在编译我的应用程序时删除所有与硬浮点相关的编译器标志,对吗?当我这样做时,我开始遇到使用硬浮点支持编译的第 3 方库之一的问题(某些双精度的 NaN 值)。我可以尝试更多地了解为什么会发生这种情况,但想确保我理解您的建议,即我仍然应该能够链接到使用硬浮点标志构建的库?
  • 如果函数使用硬浮点调用约定,您所依赖的硬浮点库应使用__attribute__((pcs("aapcs-vfp"))) 注释其标题。您不需要删除 -mfpu=neon 标志,只需删除 -mfloat-abi=hard-mhard-float(顺便说一句,它们是多余的)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-07
相关资源
最近更新 更多