You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从C代码调用时安卓动态库中OpenCV imwrite未找到问题

问题:Android aarch64架构下调用OpenCV imwrite函数出现符号未找到错误

环境与配置详情

1. 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)
...

2. 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)
...

3. 头文件(myheader.h)

#ifdef __cplusplus
extern "C"
{
#endif
   bool imwriteC(Bitmap *bitmap, const char *filename);
#ifdef __cplusplus
}
#endif

4. 实现代码(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);
}

错误信息

加载库时出现以下错误:

Unable to load library 'testlibrary':
"_ZN2cv7imwriteERKNSt6_ndk112basic_stringlcNS0_11char_traitslcEENS0_9allocatorlcEEEERKNS_11_InputArrayERKNS0_6vectorliNS4_liEEEE" referenced by ... "/path/to/testlibrary.so"...

问题分析

从错误符号来看,表面像是C++名字修饰不匹配,但核心问题有两个:

  1. 链接的OpenCV模块错误:imwrite函数属于opencv_imgcodecs模块,而非当前链接的opencv_highgui,导致库中缺少该函数的符号。
  2. STL版本可能不匹配:错误中的NSt6_ndk1表示当前代码使用NDK的libc++,若OpenCV Android SDK使用了其他STL(如gnustl),也会导致符号修饰不兼容。

解决方案

1. 修正OpenCV模块链接

修改CMakeLists.txt中的链接配置,添加opencv_imgcodecs模块:

target_link_libraries(${PROJECT_NAME} PRIVATE opencv_highgui opencv_imgcodecs)

2. 确保STL版本一致

检查OpenCV配置文件中的STL类型:

  • 打开${OpenCV_DIR}/OpenCVConfig.cmake,查找OpenCV_STL的定义(例如c++_shared)。
  • 在你的CMake工具链配置中添加对应STL设置:
    set(CMAKE_ANDROID_STL_TYPE c++_shared)
    
    注意:如果OpenCV用的是静态STL,就设置为c++_static,保持完全一致。

3. 验证链接结果

重新编译后,使用nm工具检查生成的testlibrary.so,确认imwrite的符号已被正确引入:

aarch64-linux-android-nm -D /path/to/testlibrary.so | grep imwrite

内容的提问来源于stack exchange,提问作者Flippy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 06:05:21