clang++ 对函数的未定义引用,即使它存在

clang++ undefined reference to function even though it exists

我正在尝试创建一些简单的二进制文件来调用共享对象中的导出函数 libQREngine.camera.samsung.so

这是源代码:

#include <iostream>

extern "C" int Java_com_samsung_android_qrengine_QRBarcodeDecoder_getRecogObjectCount();

int main()
{
int test=  Java_com_samsung_android_qrengine_QRBarcodeDecoder_getRecogObjectCount();
return 0;
}

这就是我尝试编译的方式 link 它:

aarch64-linux-android29-clang++ -o test test.cpp -L./lib64 -lQREngine.camera.samsung  -Wl,-rpath ./lib64

这是我收到的错误消息:

./lib64/libandroid_runtime.so: undefined reference to `jniThrowException@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniThrowNullPointerException@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniGetReferent@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniGetNioBufferBaseArrayOffset@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `JniInvocationCreate@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniThrowIOException@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniLogException@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniGetNioBufferBaseArray@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniGetFDFromFileDescriptor@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `JniInvocationDestroy@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `JniInvocationInit@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniThrowExceptionFmt@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `JNI_CreateJavaVM@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniThrowRuntimeException@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniSetFileDescriptorOfFD@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniCreateFileDescriptor@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniGetNioBufferPointer@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniGetNioBufferFields@LIBNATIVEHELPER_1'
./lib64/libandroid_runtime.so: undefined reference to `jniRegisterNativeMethods@LIBNATIVEHELPER_1'

我明白 libandroid_runtime.so 需要从 "libnativehelper.so" 导入这些函数。 在使用 readelf -d ./lib64/libandroid_runtime.so

查找时,它也被写为依赖项
0x0000000000000001 (NEEDED)             Shared library: [libnativehelper.so]

nm -D ./lib64/libnativehelper.so 也表明这些函数存在于:

00000000000034f0 T jniThrowExceptionFmt
0000000000003570 T jniThrowNullPointerException
0000000000003f58 T jniGetReferent
0000000000003d18 T jniGetNioBufferBaseArrayOffset
00000000000050e8 T JniInvocationCreate
0000000000003590 T jniThrowIOException
0000000000003608 T jniLogException
0000000000003c30 T jniGetNioBufferBaseArray

等等,为了不让 post 变大,我故意省略了一些。 Strace 还显示 libnativehelper.so 在错误发生之前的某个时刻正在打开和关闭。

现在我不明白为什么 linker 不会使用这些函数,即使它们存在于 libnativehelper.so 中并且该文件位于 ./lib64/

编辑:这似乎与 libnativehelper.so 的符号版本控制有关。正如您在上面看到的,函数 "jniThrowException" 和 "jniThrowException@LIBNATIVEHELPER_1" 完全不同,这可能是 link 用户不想 link 的原因。

是符号版本控制导致有两个功能,一个期望 "LIBNATIVEHELPER_1" 版本,而 libnativehelper.so 即使具有这些功能也无法提供该版本。

我所要做的就是通过 Google 的 AOSP 构建系统编译 libnativehelper.so(确保您在 arm64 中编译它)并获取具有该版本的版本(通过 grepping)