使用 STL 与 NDK 的运行时链接错误
Runtime linking error with NDK using STL
几天来我一直在努力在 Android 上获取 Cpp 程序,我 运行 遇到了一个我认为可能是错误的问题。我使用的是 SDL2 但没有其他库,而且我使用的是 SDL android 项目模板。
基本程序运行很好,但我想使用Cpp stdlibs和STL,所以根据说明,我添加了APP_STL := stlport_static到Application.mk并重建了程序,但此后应用程序只显示了一段时间的空白屏幕然后崩溃,调试显示如下:
01-20 22:10:14.817: D/dalvikvm(26097): Trying to load lib /data/data/com.kebabkeisari.peli/lib/libSDL2.so 0x41d06890
01-20 22:10:14.817: W/dalvikvm(26097): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lorg/libsdl/app/SDLActivity;
01-20 22:10:14.817: W/dalvikvm(26097): Class init failed in newInstance call (Lcom/kebabkeisari/peli/Ribale;)
01-20 22:10:14.822: D/AndroidRuntime(26097): Shutting down VM
01-20 22:10:14.822: W/dalvikvm(26097): threadid=1: thread exiting with uncaught exception (group=0x4109f2a0)
01-20 22:10:14.827: E/AndroidRuntime(26097): FATAL EXCEPTION: main
01-20 22:10:14.827: E/AndroidRuntime(26097): java.lang.ExceptionInInitializerError
01-20 22:10:14.827: E/AndroidRuntime(26097): at java.lang.Class.newInstanceImpl(Native Method)
01-20 22:10:14.827: E/AndroidRuntime(26097): at java.lang.Class.newInstance(Class.java:1319)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.app.Instrumentation.newActivity(Instrumentation.java:1057)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2015)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.app.ActivityThread.access0(ActivityThread.java:140)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.os.Handler.dispatchMessage(Handler.java:99)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.os.Looper.loop(Looper.java:137)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.app.ActivityThread.main(ActivityThread.java:4898)
01-20 22:10:14.827: E/AndroidRuntime(26097): at java.lang.reflect.Method.invokeNative(Native Method)
01-20 22:10:14.827: E/AndroidRuntime(26097): at java.lang.reflect.Method.invoke(Method.java:511)
01-20 22:10:14.827: E/AndroidRuntime(26097): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
01-20 22:10:14.827: E/AndroidRuntime(26097): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
01-20 22:10:14.827: E/AndroidRuntime(26097): at dalvik.system.NativeStart.main(Native Method)
01-20 22:10:14.827: E/AndroidRuntime(26097): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1307]: 1951 cannot locate 'signal'...
01-20 22:10:14.827: E/AndroidRuntime(26097): at java.lang.Runtime.loadLibrary(Runtime.java:370)
01-20 22:10:14.827: E/AndroidRuntime(26097): at java.lang.System.loadLibrary(System.java:535)
01-20 22:10:14.827: E/AndroidRuntime(26097): at org.libsdl.app.SDLActivity.<clinit>(SDLActivity.java:49)
01-20 22:10:14.827: E/AndroidRuntime(26097): ... 15 more
因此程序在 运行 时链接失败。 STL 是罪魁祸首,是的,我已经尝试过 gnustl 和其他人,但出现了同样的问题。
我正在使用 ndk-build 和 Eclipse,运行正在三星 Galaxy S3 上安装应用程序。
网上搜了一下,确实有一大堆类似的问题,有一处说不能同时build into armeabi和armeabi-v7,但是没有用。
这似乎与许多其他最近的问题相同,例如 Cannot load library: reloc_library[1285]: cannot locate 'rand'。问题是您正在使用 android-21
API 构建您的应用程序。 signal
函数(就像 rand
)曾经是 header 中的内联函数(分别将代码重定向到 bsd_signal
和 lrand48
),但在android-21
添加了新函数,因此这些函数不再内联 header。
因此,如果您希望您的应用在 android-21
之前的平台上 运行,您需要确保使用您想要的最低 API 级别构建本机代码运行 上的代码,例如通过在 jni/Application.mk
中添加 APP_PLATFORM := android-9
。
如果您需要较新功能的功能,android-19
应该也能很好地工作。对于 21 之前的版本,较新的平台版本仅添加了以前不存在的新功能(但旧功能的行为与以前一样),因此如果您仅使用 android-N 中存在的功能,它应该适用于 android-N 即使您使用 android-19
构建它(对于 N < 19)。但是 21 改变了这一切,以前存在的功能(但重定向到其他功能)现在 link 换了一个不同的名称(老实说更正确的名称),这在以前是不可用的。
这不会影响您可以构建 java 代码(如果有)的 API 级别,但是 - 您仍然可以针对最新的 API 构建该部分,如果你想。
几天来我一直在努力在 Android 上获取 Cpp 程序,我 运行 遇到了一个我认为可能是错误的问题。我使用的是 SDL2 但没有其他库,而且我使用的是 SDL android 项目模板。
基本程序运行很好,但我想使用Cpp stdlibs和STL,所以根据说明,我添加了APP_STL := stlport_static到Application.mk并重建了程序,但此后应用程序只显示了一段时间的空白屏幕然后崩溃,调试显示如下:
01-20 22:10:14.817: D/dalvikvm(26097): Trying to load lib /data/data/com.kebabkeisari.peli/lib/libSDL2.so 0x41d06890
01-20 22:10:14.817: W/dalvikvm(26097): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lorg/libsdl/app/SDLActivity;
01-20 22:10:14.817: W/dalvikvm(26097): Class init failed in newInstance call (Lcom/kebabkeisari/peli/Ribale;)
01-20 22:10:14.822: D/AndroidRuntime(26097): Shutting down VM
01-20 22:10:14.822: W/dalvikvm(26097): threadid=1: thread exiting with uncaught exception (group=0x4109f2a0)
01-20 22:10:14.827: E/AndroidRuntime(26097): FATAL EXCEPTION: main
01-20 22:10:14.827: E/AndroidRuntime(26097): java.lang.ExceptionInInitializerError
01-20 22:10:14.827: E/AndroidRuntime(26097): at java.lang.Class.newInstanceImpl(Native Method)
01-20 22:10:14.827: E/AndroidRuntime(26097): at java.lang.Class.newInstance(Class.java:1319)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.app.Instrumentation.newActivity(Instrumentation.java:1057)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2015)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.app.ActivityThread.access0(ActivityThread.java:140)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.os.Handler.dispatchMessage(Handler.java:99)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.os.Looper.loop(Looper.java:137)
01-20 22:10:14.827: E/AndroidRuntime(26097): at android.app.ActivityThread.main(ActivityThread.java:4898)
01-20 22:10:14.827: E/AndroidRuntime(26097): at java.lang.reflect.Method.invokeNative(Native Method)
01-20 22:10:14.827: E/AndroidRuntime(26097): at java.lang.reflect.Method.invoke(Method.java:511)
01-20 22:10:14.827: E/AndroidRuntime(26097): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
01-20 22:10:14.827: E/AndroidRuntime(26097): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
01-20 22:10:14.827: E/AndroidRuntime(26097): at dalvik.system.NativeStart.main(Native Method)
01-20 22:10:14.827: E/AndroidRuntime(26097): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1307]: 1951 cannot locate 'signal'...
01-20 22:10:14.827: E/AndroidRuntime(26097): at java.lang.Runtime.loadLibrary(Runtime.java:370)
01-20 22:10:14.827: E/AndroidRuntime(26097): at java.lang.System.loadLibrary(System.java:535)
01-20 22:10:14.827: E/AndroidRuntime(26097): at org.libsdl.app.SDLActivity.<clinit>(SDLActivity.java:49)
01-20 22:10:14.827: E/AndroidRuntime(26097): ... 15 more
因此程序在 运行 时链接失败。 STL 是罪魁祸首,是的,我已经尝试过 gnustl 和其他人,但出现了同样的问题。
我正在使用 ndk-build 和 Eclipse,运行正在三星 Galaxy S3 上安装应用程序。
网上搜了一下,确实有一大堆类似的问题,有一处说不能同时build into armeabi和armeabi-v7,但是没有用。
这似乎与许多其他最近的问题相同,例如 Cannot load library: reloc_library[1285]: cannot locate 'rand'。问题是您正在使用 android-21
API 构建您的应用程序。 signal
函数(就像 rand
)曾经是 header 中的内联函数(分别将代码重定向到 bsd_signal
和 lrand48
),但在android-21
添加了新函数,因此这些函数不再内联 header。
因此,如果您希望您的应用在 android-21
之前的平台上 运行,您需要确保使用您想要的最低 API 级别构建本机代码运行 上的代码,例如通过在 jni/Application.mk
中添加 APP_PLATFORM := android-9
。
如果您需要较新功能的功能,android-19
应该也能很好地工作。对于 21 之前的版本,较新的平台版本仅添加了以前不存在的新功能(但旧功能的行为与以前一样),因此如果您仅使用 android-N 中存在的功能,它应该适用于 android-N 即使您使用 android-19
构建它(对于 N < 19)。但是 21 改变了这一切,以前存在的功能(但重定向到其他功能)现在 link 换了一个不同的名称(老实说更正确的名称),这在以前是不可用的。
这不会影响您可以构建 java 代码(如果有)的 API 级别,但是 - 您仍然可以针对最新的 API 构建该部分,如果你想。