【问题标题】:STLport and Android NDK - STLport loaded as static, Linux/gcc ld reports "multiple definitions"STLport 和 Android NDK - STLport 作为静态加载,Linux/gcc ld 报告“多个定义”
【发布时间】:2014-02-08 02:47:10
【问题描述】:

我浏览了很多关于 Android NDK 和 STLport 的资料。我有复杂的应用程序,java+native 代码,它加载 STLport(一个 c++ 标准库端口)。原始代码库在项目的“jni”子目录中的 Application.mk 中有“APP_STL := stlport_static”。导致 ld 加载静态库。在当前的 SDK/NDK 中,这导致了许多编译失败。

根据建议,尝试加载为动态库。 (在“../jni/Application.mk”中,设置“APP_STL := stlport_shared”)有了这个,我得到一个干净的编译和加载,应用程序在 Android armeabi 上运行完美- v7a 模拟器,if 我在“dalvik”虚拟机上禁用了 checkJNI。

但是一旦我启用 checkJNI,我在 libapplication.so 上得到一个“unsatisfiedLinkError”,这看起来可能是由于 STLport 被动态加载造成的。所以,我想在静态模式下加载 STLport(logcat 在其他几个库成功加载后报告这个)。在构建过程中,编译是可以的,但是我得到了两个多重定义错误,特别是:“'vtable for std::bad_exception' 的多重定义”和 'std::exception::~exception()'。 (我也尝试过使用“gnustl_static”)。

我正在使用 gcc 版本 4.3.0 并制作版本 3.81、命令行模式和围绕 build-ndk 的小型包装器,用于 android ndk-r9c,构建目标版本为 android-8,“ant”来构建.apk 文件等。

比我更熟悉 Android 的人(我是一个完全的菜鸟)可能以前见过这个。如果有,请指教。谢谢。 - 罗斯

【问题讨论】:

  • 使用stlport_static会出现什么错误?我认为只要有效,您使用的是共享的还是静态的都没关系?
  • 我在 Application.mk 中尝试了“APP_STL := stlport_shared”。加载干净,但“Davlik”虚拟机在加载一些库后在应用程序 libapplication.so 上因“unsatisfiedLinkError”而崩溃。原始代码库使用静态库。我在想也许静态库使用本地指针(?)所以也许静态加载修复了 dalvik unsatisfiedLinkError? (代码在 armeabi-v7a 模拟器上完美运行,“dalvik.vm.checkjni”属性设置为 false。)关于 stlport 的多重定义 std::exception() 的问题,谷歌搜索很多。现在读。这里有一个解决方案...... ;)
  • 有趣...我正在使用 stlport_static 没问题,只是想知道你还在做什么而我不是。
  • 我还没有尝试过,但我相信您可以通过在您的 Android.mk 文件中包含include external/stlport/Android.mk 将其构建为静态库。您可能需要更新您的 LOCAL_C_INCLUDES 并将 libstlport 添加到您的 LOCAL_SHARED_LIBRARIES。我会说试试看。不过,您可能需要在源代码中添加一些定义才能使其正常工作。

标签: android android-ndk stlport


【解决方案1】:

绝对可以将 stlport_static 与 NDK r9c 一起使用。 多重定义错误提到了哪些目标文件?也许,您正在使用一些预建库?也许,gcc 4.3 版有问题?为什么不使用默认的(gcc 4.8)?

因此,NDK document 明确鼓励使用共享 STL,但您不能忘记按正确顺序调用 System.loadLibrary()

System.loadLibrary("stlport_shared");
System.loadLibrary("Rusfuture");

【讨论】:

  • 谢谢,亚历克斯和丹尼。我已经让它工作了。将“stlport”作为静态加载解决了 dalvik 的 unsatisfiedLinkError 问题。多个定义涉及stlport中的异常处理代码,在prgm“dll_main.cpp”中(我刚刚在dll_main.cpp中注释掉了以下六行)#if defined (_STLP_NO_EXCEPTION_HEADER) ||已定义 (_STLP_BROKEN_EXCEPTION_CLASS) // --- MCL mod。在加载时生成“多个定义”失败...暂时删除 // exception::exception() _STLP_NOTHROW {} // exception::~exception() _STLP_NOTHROW {}
  • 这是被删除的代码:code #if defined (_STLP_NO_EXCEPTION_HEADER) || defined (_STLP_BROKEN_EXCEPTION_CLASS) // --- MCL mod.. 这会在加载时产生“多个定义”失败...暂时删除 // exception::exception() _STLP_NOTHROW {} // exception::~exception() _STLP_NOTHROW {} // bad_exception::bad_exception() _STLP_NOTHROW {} // bad_exception::~bad_exception() _STLP_NOTHROW {} // const char* exception::what() const _STLP_NOTHROW { return "class exception"; } // const char* bad_exception::what() const _STLP_NOTHROW { return "class bad_exception"; } #endif code
  • 只是为了清楚。这是一个很大的结果。我现在可以使用 adb 将 .apk 的调试版本(使用 r9c android ndk/sdk 和“ant-debug” - 在命令行模式下使用 Fedora Linux 构建)放到运行 Android 4.1.1 的实际真实设备上(一个便宜的“Digital2”平板电脑),它运行和表现都很好。关键是将目标构建设置为“android-8”,静态加载 STLport,因此我怀疑 dalvik-vm 加载可以解析内部库引用。
  • 可能这个dll_main.cpp 是特定于Windows 的?
猜你喜欢
  • 2011-06-01
  • 2011-07-11
  • 2011-05-19
  • 2012-05-11
  • 1970-01-01
  • 2010-12-11
  • 2014-09-07
  • 2012-03-23
相关资源
最近更新 更多