对函数 Android NDK 的未定义引用

Posted

技术标签:

【中文标题】对函数 Android NDK 的未定义引用【英文标题】:Undefined reference to function Android NDK 【发布时间】:2016-08-03 10:38:02 【问题描述】:

我正在尝试使用现有的使用 OpenCV 的 c++ 代码构建 android 应用程序。 但 Android NDK 表示“未定义对 'TestMath::getHello()' 的引用”

这是我的 Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
#opencv
OPENCVROOT := /mypath/OpenCV-android-sdk
OPENCV_CAMERA_MODULES := off
OPENCV_INSTALL_MODULES := off
OPENCV_LIB_TYPE := SHARED
include $OPENCVROOT/sdk/native/jni/OpenCV.mk

LOCAL_MODULE := CrossMath
LOCAL_SRC_FILES := com_testapp_recognition_TestMath.cpp
LOCAL_SHARED_LIBRARIES := -lopencv_java3
include $(BUILD_SHARED_LIBRARY)

应用程序.mk:

APP_ABI := all
APP_CPPFLAGS := -frtti -fexceptions -std=c++11
APP_STL := gnustl_static
APP_PLATFORM := android-16

com_testapp_recognition_TestMath.hpp:

#include <jni.h>
#include "CrossMath/TestMath.hpp"
#ifndef _Included_com_testapp_recognition_TestMath
#define _Included_com_testapp_recognition_TestMath

#ifdef __cplusplus
extern "C" 
#endif

JNIEXPORT jint JNICALL Java_com_testapp_recognition_TestMath_recognize(JNIEnv *, jobject, cv::Mat& originalImage);

#ifdef __cplusplus

#endif
#endif

com_testapp_recognition_TestMath.cpp:

#include "com_testapp_recognition_TestMath.hpp"
JNIEXPORT jint JNICALL Java_com_testapp_recognition_TestMath_recognize(JNIEnv *, jobject, cv::Mat& originalImage) 
     return TestMath::getHello().size();

最后是位于子文件夹 CrossMath 中的 TestMath.cpp:

#include "TestMath.hpp"

namespace TestMath 
     string getHello() 
         return "Hello";
     

TestMath.hpp:

#ifndef TestMath_hpp
#define TestMath_hpp

#include <stdio.h>
#include <iostream>
#include "opencv2/core/core_c.h"
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"

namespace TestMath 
    string getHello();

Java 类和其他人员已定义,我检查了路径并包含在文件中。

错误:

Error:(13) undefined reference to `TestMath::getHello()'

【问题讨论】:

请添加完整且准确的错误消息。我真的不明白CrossMath/TestMath.hpp 的意义。函数实现不应该放在头文件中。 @Michael 这显然是错字... string 应该是什么? std::string?如果是这样,你在哪里包括&lt;string&gt;,你在哪里声明你希望它是std命名空间中的string 如果问题出在字符串类型错误将是另一个,无论如何,我添加了 没有任何改变。 【参考方案1】:

您的LOCAL_SRC_FILES 中缺少CrossMath/TestMath.cpp

除此之外,如果您在代码中引用的string 应该是std::string,您需要在TestMath.hpp 中包含&lt;string&gt; 并将类型更改为std::string

【讨论】:

根据android.mk“你不需要在你的Android.mk中列出头文件或生成的文件之间的显式依赖关系”或者这意味着不放.hpp文件? 指的是头文件和生成的文件(不管是什么意思)。 LOCAL_SRC_FILES 应包含“构建系统用于生成模块的源文件列表”【参考方案2】:

错误消息“未定义对 'TestMath::getHello()' 的引用”表示 NDK 工具找不到 TestMath::getHello() 的实现。 试试下面的 com_testapp_recognition_TestMath.cpp:

#include "TestMath.hpp"
namespace TestMath 
    string getHello() 
        return "Hello";
    

#include "com_testapp_recognition_TestMath.hpp"
    JNIEXPORT jint JNICALL Java_com_testapp_recognition_TestMath_recognize(JNIEnv *, jobject, cv::Mat& originalImage) 
    return TestMath::getHello().size();

【讨论】:

主要目标是不在 com_testapp_recognition_TestMath.cpp 中编写整个实现。但包括部分纯 c++ 代码以从 JNI 包装器运行。

以上是关于对函数 Android NDK 的未定义引用的主要内容,如果未能解决你的问题,请参考以下文章

在android NDK中包含本地头文件时的未定义引用

Android FFmpeg:对atof,log2和log2f的未定义引用

在android中使用JNI对“乘法”的未定义引用

对共享库函数的未定义引用

linux makefile中对函数的未定义引用

在库的情况下对函数的未定义引用