clang ++ undefined ссылка на функцию, даже если она существует - PullRequest
0 голосов
/ 26 мая 2020

Я пытаюсь создать простой двоичный файл для вызова экспортируемой функции из общего объекта 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;
}

Это вот как я пытаюсь скомпилировать и связать его:

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

И так далее, я специально кое-что упустил, чтобы этот пост не увеличивался. Strace также показывает, что libnativehelper.so открывается и закрывается в какой-то момент до возникновения ошибки.

Теперь я не понимаю, почему компоновщик не будет использовать эти функции, даже если они существуют внутри libnativehelper.so и что файл находится внутри ./lib64/

Edit: Похоже, это как-то связано с управлением версиями символов libnativehelper.so. Как вы можете видеть выше, функции «jniThrowException» и «jniThrowException@LIBNATIVEHELPER_1» немного отличаются, что, вероятно, является причиной того, что компоновщик не хочет связывать их.

1 Ответ

0 голосов
/ 29 мая 2020

Это было символьное управление версиями, которое привело к появлению двух функций: одна ожидала версию "LIBNATIVEHELPER_1", в то время как libnativehelper.so не мог предоставить эту версию, даже если у него были эти функции.

Все, что мне нужно было do было скомпилировать libnativehelper.so через систему сборки Googles AOSP (убедитесь, что вы скомпилировали ее в arm64) и взять ту, у которой была эта версия (с помощью grepping)

...