I am using OpenCV 4.6.0 Android SDK which I downloaded from sourceforge and use it within my shared library/.so. This library is called from within my android app (aarch64). Building works fine using my android.toolchain.cmake :
...
set(CMAKE_C_COMPILER /home/username/Android/SDK/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang)
set(CMAKE_CXX_COMPILER /home/username/Android/SDK/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang )
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 21)
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
set(CMAKE_ANDROID_NDK /home/username/Android/Sdk/ndk/25.1.8937393)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
...
And CMakeLists.txt:
...
set(OpenCV_DIR ${CMAKE_CURRENT_LIST_DIR}/opencv-4.6.0-android-sdk/OpenCV-android-sdk/sdk/native/jni/abi-arm64-v8a)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/opencv-4.6.0-android-sdk/OpenCV-android-sdk/sdk/native/jni/include)
find_package(OpenCV REQUIRED)
...
target_link_libraries(${PROJECT_NAME} PRIVATE opencv_highgui)
...
My .h
#ifdef __cplusplus
extern "C"
{
#endif
bool imwriteC(Bitmap *bitmap, const char *filename);
#ifdef __cplusplus
}
#endif
And .cpp
#include <opencv2/opencv.hpp>
#include "myheader.h"
...
bool imwriteWrapper(Bitmap *bitmap, const char *filename)
{
Mat mat;
// ...
// bitmap to mat conversion here
// ...
return imwrite(filename, mat);
}
bool imwriteC(Bitmap *bitmap, const char *filename) {
return imwriteWrapper(bitmap, filename);
}
I call my imwriteC
from C-Code.
My error message looks like name-mangling
Unable to load library 'testlibrary':
"_ZN2cv7imwriteERKNSt6_ndk112basic_stringlcNS0_11char_traitslcEENS0_9allocatorlcEEEERKNS_11_InputArrayERKNS0_6vectorliNS4_liEEEE" referenced by ... "/path/to/testlibrary.so"...
So it seems like OpenCVs imwrite
can't be found due to name mangling issues(?).
CodePudding user response:
It's not about mangling, you just didn't link with all the OpenCV libraries that you need.
You're using OpenCV version 4.6.0. I see that you're calling imwrite
, and you're linking with the highgui
module. Well, once upon a time (in 2.4.x) that would have worked, but IIRC since 3.x (and definitely in 4.x) this function resides in imgcodecs
module. So you should change that target_link_libraries
statement to something like
target_link_libraries(${PROJECT_NAME} PRIVATE opencv_imgcodecs)
Furthermore, since you're using a Mat
there, you might need the core
module. Often you can figure out the name of the module from the documentation (best look at the URL -- for imwrite
there's group__imgcodecs.html
in the middle, and the module name is after the two underscores).
Of course, as you found out, since you find_package(OpenCV REQUIRED)
, you can also take the shortcut and link with ${OpenCV_LIBS}
, which ends up trying all the OpenCV modules. I guess that's good enough choice, although personally I prefer to explicitly specify exactly what I need and no more.