【问题标题】:Compile JNI library that includes OpenCV headers编译包含 OpenCV 头文件的 JNI 库
【发布时间】:2026-01-20 07:25:01
【问题描述】:

喂!

我有一个需要编译的带有 cpp 文件的 Android 项目。该文件包括 OpenCV 库的一些头文件。如您在 Android.mk 文件中所见,OpenCV 源文件位于 jni/include/opencv2 文件夹下。当我尝试使用 ndk-build 编译该文件时,编译器会给出以下错误:

"undefined reference to"

这似乎是所有这些文件的“错误:未定义引用”问题。

Android.mk 文件有以下内容:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

OPENCV_PACKAGE_DIR := $(LOCAL_PATH)/include

LOCAL_MODULE := iqindex

LOCAL_C_INCLUDES := \
    $(LOCAL_PATH) \
    $(OPENCV_PACKAGE_DIR)

LOCAL_SRC_FILES := \
    main.cpp

LOCAL_SHARED_LIBRARIES := iqindex

LOCAL_LDLIBS := -llog -lz

include $(BUILD_SHARED_LIBRARY)

我在 jni/ndk 方面没有足够的经验,我的问题是:

  1. 编译一个.cpp文件需要另外一个头文件就够了,用ndk-build命令编译就可以了?

  2. 我尝试编译它有什么问题? Android.mk 出了什么问题?

编辑:控制台错误如下:

C:\MyName\My Project App>ndk-build

C:/MyName/android-ndk-r8e/build/core/add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 8 in ./AndroidManifest.xml
SharedLibrary  : libiqindex.so

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o:(.ARM.extab.text.unlikely._ZL6jthrowP7_JNIEnv+0x2c): error: undefined reference to 'typeinfo for cv::Exception'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function cv::Mat::Mat(cv::Mat const&):jni/include/opencv2/core/mat.hpp:125: error: undefined reference to 'cv::Mat::copySize(cv::Mat const&)'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function cv::Mat::release():jni/include/opencv2/core/mat.hpp:364: error: undefined reference to 'cv::Mat::deallocate()'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function cv::Mat::~Mat():jni/include/opencv2/core/mat.hpp:278: error: undefined reference to 'cv::fastFree(void*)'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function Java_project_name_zxing_Mat_submat_1n:jni/include/opencv2/core/mat.hpp:376: error: undefined reference to 'cv::Mat::Mat(cv::Mat const&, cv::Rect_<int> const&)'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function Java_project_name_zxing_Mat_resize_1n:jni/main.cpp:111: error: undefined reference to 'cv::_InputArray::_InputArray(cv::Mat const&)'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function Java_project_name_zxing_Mat_resize_1n:jni/main.cpp:111: error: undefined reference to 'cv::_OutputArray::_OutputArray(cv::Mat&)'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function Java_project_name_zxing_Mat_resize_1n:jni/main.cpp:111: error: undefined reference to 'cv::resize(cv::_InputArray const&, cv::_OutputArray const&, cv::Size_<int>, double, double, int)'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function Java_project_name_zxing_Utils_rotateData:jni/main.cpp:124: error: undefined reference to'cv::_InputArray::_InputArray(cv::Mat const&)'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function Java_project_name_zxing_Utils_rotateData:jni/main.cpp:124: error: undefined reference to'cv::_OutputArray::_OutputArray(cv::Mat&)'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function Java_project_name_zxing_Utils_rotateData:jni/main.cpp:124: error: undefined reference to'cv::flip(cv::_InputArray const&, cv::_OutputArray const&, int)'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function Java_project_name_zxing_Utils_rotateData:jni/main.cpp:125: error: undefined reference to'cv::Mat::t() const'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function Java_project_name_zxing_IQLocal_nativeCreate:jni/main.cpp:139: error: undefined reference to 'get_instance()'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function Java_project_name_zxing_IQLocal_load:jni/main.cpp:156: error: undefined reference to 'IQIndex::load(std::string, std::string)'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function Java_project_name_zxing_IQLocal_match:jni/main.cpp:171: error: undefined reference to 'IQIndex::match(cv::Mat&)'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function Java_project_name_zxing_IQLocal_train:jni/main.cpp:182: error: undefined reference to 'IQIndex::train()'

C:/MyName/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi-v7a/objs/iqindex/main.o: in function Java_project_name_zxing_IQLocal_compute:jni/main.cpp:198: error: undefined reference to 'IQIndex::compute(cv::Mat const&, char const*, char const*)'

collect2: ld returned 1 exit status

make: *** [obj/local/armeabi-v7a/libiqindex.so] Error 1

第二次编辑:现在 Android.mk 看起来像这样:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# OpenCV
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on

include C:/Emil/downloads/OpenCV-2.4.6-android-sdk-r2/OpenCV-2.4.6-android-sdk/sdk    /native/jni/OpenCV.mk

LOCAL_MODULE := iqindex

LOCAL_SRC_FILES := \
    main.cpp

LOCAL_C_INCLUDES := \
    $(LOCAL_PATH)/iqindex.h

LOCAL_LDLIBS := -llog -lz

include $(BUILD_SHARED_LIBRARY)

【问题讨论】:

  • 你能发布完整的错误吗?这看起来像是一个链接器错误。

标签: android opencv compilation android-ndk java-native-interface


【解决方案1】:

我想您忘记将 OpenCV 库添加到您的项目中。所以链接器找不到OpenCV相关函数。

From OpenCV documentation:

如果您的应用程序项目没有 JNI 部分,只需复制 相应的 OpenCV 本机库来自 /sdk/native/libs/ 到你的 项目目录到文件夹 libs/。

如果应用程序项目带有 JNI 部分,而不是手动 库复制您需要修改您的 Android.mk 文件:添加 在“include $(CLEAR_VARS)”之后和之前的两行代码 “包括 path_to_OpenCV-2.4.6-android-sdk/sdk/native/jni/OpenCV.mk OPENCV_CAMERA_MODULES:=on OPENCV_INSTALL_MODULES:=on

所以你的 Android.mk 中应该有以下几行:

include $(CLEAR_VARS)
# OpenCV
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
include ../../sdk/native/jni/OpenCV.mk

【讨论】:

  • 我做了你在这里写的,“未定义的对”OpenCV 的引用消失了。 Android.mk 在第二次编辑后。现在我有另一个问题:我在 jni 文件夹中有一个名为 iqindex.h 的头文件。 cpp 文件包含它,但现在我在尝试构建时有“未定义的引用”iqindex.h。我在 Android.mk 中尝试了指向头文件的 LOCAL_C_INCLUDES 命令,但是在编译时它不再看到 openCV。如何包含此标头以使文件编译?
  • 有时,在 Android 的情况下;在 Android.mk 中提及 'LOCAL_LDLIBS := -lz -lm -llog -landroid -ldl' 会起作用..
【解决方案2】:

这是迟到了,但响应:

现在我有另一个问题:我在 jni 文件夹中有一个名为 iqindex.h 的头文件。 cpp 文件包含它,但现在我在尝试构建时有“未定义的引用”iqindex.h。我在 Android.mk 中尝试了指向头文件的 LOCAL_C_INCLUDES 命令,但是在编译时它不再看到 openCV。如何包含此标头以使文件编译?

问题可能是你使用了LOCAL_C_INCLUDES :=/foo/bar

试试LOCAL_C_INCLUDES +=/foo/bar。 您应该添加包含目录,而不是覆盖现有的包含。

【讨论】:

  • 重要提示:LOCAL_C_INCLUDES 列出目录,而不是单个包含文件!