Ift*_*tah 8 android android-ndk
最近我升级了NDK,现在我的应用程序因缺少符号而崩溃mkfifo:
E/dalvikvm(2031): dlopen("/data/app-lib/...mylib.so") failed: Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "mkfifo" referenced by "mylib.so"...
Run Code Online (Sandbox Code Playgroud)
较旧的平台mkfifo是内联定义的 sys/stat.h
static __inline__ int mkfifo(const char *__p, mode_t __m) {
return mknod(__p, (__m & ~S_IFMT) | S_IFIFO, (dev_t)0);
}
Run Code Online (Sandbox Code Playgroud)
但是在平台版本21中,它被改为仅仅是一个外部的decleration:
extern int mkfifo(const char*, mode_t);
Run Code Online (Sandbox Code Playgroud)
这就解释了缺失的符号异常...我的问题是如何解决它?
mst*_*sjo 26
如果您针对android-21平台标头构建,则会发生这种情况 坐落APP_PLATFORM在jni/Application.mk旧版本,使用旧的头,以确保您只能链接到可用的早期功能来构建.
(之前android-21,C库功能和头并没有真正显著变化,因此对于普通的C库函数,它不如果你建立针对重要android-3或android-20).
这已被报道并且是故意行为,请参阅https://code.google.com/p/android/issues/detail?id=73725.
如果您不需要使用新功能android-21,只需使用较旧的标头构建.(如果您想尝试构建例如以前不存在的arm64-v8a或者x86_64之前不存在的平台版本,则无关紧要; ndk-build使用较旧的目标构建32位部分,使用较旧的目标构建64位部分支持他们的最古老的目标.)
如果您想要在android-21平台上运行时尝试有条件地使用平台上的新功能,您可能需要使用dlopen和dlsym有条件地加载它,因此您需要复制新标头中的其他定义,以及允许您使用较旧的平台标头进行构建.
小智 9
我已经尝试了mstorsjo的修复,它似乎工作,但我有点担心,从他发布的链接似乎谷歌并不认为这是一个好主意.结果我做了一些挖掘,似乎'正确'修复是运送多个APK,(至少)一个目标android-20及以下,另一个目标android-21及以上.
该问题源于NDK的变化,以在执行NDK构建时强制使用'fPIE'选项.从NDK 10d发行说明:
从API级别21开始,在构建时使用-fPIE -pie.在API级别16及更高级别中,ndk-build在构建时使用PIE.此更改有许多含义,在开发人员预览版888中进行了讨论.这些含义不适用于共享库.
如果查看Developer Preview Issue 888,它会说明以下内容:
Bionic commit 76e289c026f及其前身2aebf5429bb要求使用-fPIE -pie构建所有动态链接的本机可执行文件.这有许多可能无意的副作用,包括:
在KitKat下正常工作的旧/未维护的应用程序现在可能无法在"L"下运行.这甚至可能会影响不使用网络的简单应用程序,处理不受信任的数据或定位新的"L"SDK API.
希望以"L"为目标的主动维护应用程序必须提供PIE可执行文件或静态可执行文件. 如果某个应用想要定位ICS或更低版本,则还必须提供非PIE可执行文件或静态可执行文件.即使是使用-fPIE -pie构建的简单"Hello world"程序也会在ICS和GB上发生段错误.
显然,您可能更愿意使用之前的解决方案,但只是认为值得注意.
| 归档时间: |
|
| 查看次数: |
9354 次 |
| 最近记录: |