0

嗨!

我有一个需要编译的带有 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)
4

2 回答 2

2

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

来自 OpenCV 文档:

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

对于带有 JNI 部分的应用程序项目,您需要修改 Android.mk 文件,而不是手动复制库:在“include $(CLEAR_VARS)”之后和“include 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
于 2013-07-24T15:51:44.087 回答
1

这已经很晚了,但是为了回应:

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

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

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

于 2015-06-03T12:45:41.717 回答