gpt4 book ai didi

android-ndk - Android NDK 共享对象 undefined reference 错误

转载 作者:行者123 更新时间:2023-12-02 04:25:03 29 4
gpt4 key购买 nike

我在尝试为 Android 编译代码时遇到了一个奇怪的问题。我的代码与两个第三方库(libcurl 和 WebRTC)连接,当它进入链接阶段(链接到编译的共享对象文件)时,它报告 WebRTC 中存在对函数的 undefined reference ,但 libcurl 函数很好。我得到的未定义错误的例子是:

WS.cpp:208: error: undefined reference to 'buzz::XmlElement::AddAttr(buzz::QName const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)'

ThirdPartyLibs/WebRTC/src/third_party/android_tools/ndk/sources/cxx-stl/llvm-libc++/libcxx/include/memory:1636: error: undefined reference to 'buzz::QN_MESSAGE'

当我跑 nm -C在 WebRTC 库文件上,然后 grep函数的结果,函数清楚地显示存在和定义(在文本部分)。
nm -C Android/libs/armv7/libWebRTC.so | grep "AddAttr"
000753e5 t buzz::XmlElement::AddAttr(buzz::QName const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
0007541d t buzz::XmlElement::AddAttr(buzz::QName const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)

nm -C kino/Android/libs/armv7/libWebRTC.so | grep "QN_MESSAGE"
000bfd10 d buzz::QN_MESSAGE

当我说我正在链接一个编译的 WebRTC 共享库时,我应该注意到共享库是使用 ninja 编译的静态库或对象文件编译的。我正在使用以下内容进行编译:
GCC_armv7=$projectDir/ThirdPartyLibs/WebRTC/src/third_party/android_tools/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc

OBJS_armv7="…list of static libraries or object files…”

LDFLAGS="-lc -ldl -lm -fPIC
--sysroot=$projectDir/ThirdPartyLibs/WebRTC/src/third_party/android_tools/ndk/platforms/android-16/arch-arm
-L$projectDir/ThirdPartyLibs/WebRTC/src/third_party/android_tools/ndk/platforms/android-16/arch-arm/usr/lib/"

$GCC_armv7 -v -shared $LDFLAGS -o libWebRTC.so -Wl,-soname=webrtc $OBJS_armv7

当我将代码直接链接到 ninja 编译的静态库文件或 ninja 编译的目标文件时,我不会遇到相同的错误。由于它有效,因此只需链接其中任何一个就好了。但是,Java Android 开发人员告诉我,尽管 Java 接受静态库,但 Android 不接受。而且我无法想象 Java 或 Android 会针对目标文件进行编译。

我还不得不在 Android.mk 文件中强制引用 LOCAL_LDLIBS 参数中的文件,而不是使用 LOCAL_SHARED_LIBRARIES 或 LOCAL_STATIC_LIBRARIES 参数。

当我尝试使用前一种方法时,ndk-build 似乎永远找不到合适的库文件。相反,它似乎使用了 libcurl 和 libopenssl 库的系统版本。

作为健全性检查,我运行了相同的 nm | grep对目标文件和静态库文件执行命令,并将它们与共享目标文件的结果进行比较。下面是 nm –C | grep的对比静态/目标文件和编译后的so文件之间的结果。
static / object -
00000001 T buzz::XmlElement::AddAttr(buzz::QName const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)

shared object -
000753e5 t buzz::XmlElement::AddAttr(buzz::QName const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)

从我能够收集到的输出 nm ,“T”和“t”之间没有区别,但我不明白为什么它会在两组之间发生变化。

我应该注意到,所使用的 gcc(或 g++)编译器是 WebRTC 下载( commit hash: aad6780e5c25b1622904ef83659461706f6a25db )提供的相应架构的特定 gcc/g++ 二进制文件。对于 ndk-build(ing),我还使用了 WebRTC 下载 ( src/chromium/src/third_party/android_tools/ndk/ndk-build ) 附带的 ndk-build 二进制文件。

我的问题:我做错了什么,以至于链接目标文件将编译一个 ndk-build Android.mk 文件,但是链接共享目标文件将失败,其中一些函数被定义而另一个未被定义?

更新:我只是尝试使用 ndk-build 和 Android.mk 文件而不是 gcc/g++ 来编译 so 文件,但我遇到了同样的错误。

最佳答案

我想出了解决这个问题的方法。我没有尝试为 WebRTC 构建单独的共享对象文件,而是回到了直接链接编译对象文件的路线。这样做会强制 ndk-build 在我的代码的编译共享对象文件中包含这些对象。因此,我的最终库 .so 文件比计划的要大得多。但这并不重要,因为它保存了我们正在使用的所有 WebRTC 库。对于那些有类似问题的人,请注意 ./libs/<arch>/ 中的编译库文件。文件夹被剥离下来的符号。所以如果你 nm | grep他们,你会得到一个错误。如果您需要使用该命令进行任何类型的完整性检查,请使用 ./obj/local/<arch> 中的编译库反而。

我不会接受这个答案,以防其他人出现并且能够在没有解决方法的情况下实际解决问题。

关于android-ndk - Android NDK 共享对象 undefined reference 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40345122/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com