Android NDK / JNI - 对自定义头文件中定义的函数的未定义引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22159183/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:35:04  来源:igfitidea点击:

Android NDK / JNI - undefined reference to function defined in custom header file

androidc++candroid-ndkjava-native-interface

提问by Pink Jazz

Using JNI, I am trying to write a native C++ method for the Android NDK that makes a call to a C function defined in a custom header file. However, I am getting an undefined reference error for my C function call.

使用 JNI,我尝试为 Android NDK 编写本机 C++ 方法,该方法调用自定义头文件中定义的 C 函数。但是,我的 C 函数调用出现未定义的引用错误。

Here is my C++ code that makes a call to the C function and returns its result to Java as a jstring:

这是我的 C++ 代码,它调用 C 函数并将其结果作为 jstring 返回给 Java:

#include <jni.h>

#include "gesture_detector.h"

JNIEXPORT jstring JNICALL Java_com_example_bmtitest_JavaAbstractionLayer_callGestureAnalysis(JNIEnv *env, jobject obj, jfloat previousX, jfloat previousY, jfloat currentX, jfloat currentY) {
    return env->NewStringUTF(gestureAnalysis(previousX, previousY, currentX, currentY));
}

Here is my C function:

这是我的 C 函数:

#include <stdio.h>

#include "gesture_detector.h"

//implemented from gesture_detector.h
const char* gestureAnalysis(float previousX, float previousY, float currentX, float currentY)
{
    float xOffset = currentX - previousX;
    float yOffset = currentY - previousY;

    if(xOffset == 0 && yOffset == 0)
    {
        return "TAP";
    }
    return "0";
}

Here is my Android.mk code:

这是我的 Android.mk 代码:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := gestureDetector
LOCAL_SRC_FILES := gestureDetector.c NativeAbstractionLayer.cpp
LOCAL_LDLIBS    := -landroid

include $(BUILD_SHARED_LIBRARY)

Apparently, it seems the function definition defined in the custom header file (gesture_detector.h) isn't being found. I think it may be a problem in my Android.mk file.

显然,似乎gesture_detector.h没有找到自定义头文件 ( ) 中定义的函数定义。我认为这可能是我的 Android.mk 文件中的问题。

Could anyone tell me what am I doing wrong here?

谁能告诉我我在这里做错了什么?

回答by Chris Stratton

An "undefined reference" error comes from the linker. Your header file only satisfied the compiler.

“未定义引用”错误来自链接器。您的头文件只满足编译器。

However, since you are mixing C and C++ your problem is likely name mangling. Basically, you need to tell the C++ compiler that the function you are trying to call was created by a C compiler rather than a C++ one, and so does not have argument type codes grafted onto its name. Right now it doesn't know that, so is trying to call the function by a C++ style decorated name which differs from the plain C name of the function the linker actually has available.

但是,由于您混合使用 C 和 C++,您的问题可能是name mangling。基本上,您需要告诉 C++ 编译器您尝试调用的函数是由 C 编译器创建的,而不是由 C++ 编译器创建的,因此没有将参数类型代码嫁接到其名称上。现在它不知道这一点,因此试图通过 C++ 风格的装饰名称调用该函数,该名称不同于链接器实际可用的函数的纯 C 名称。

Add this at the beginning of your gesture_detector.h file:

在你的gesture_detector.h 文件的开头添加:

#ifdef __cplusplus
extern "C" {
#endif

And this at the end

而这最后

#ifdef __cplusplus
}
#endif

And do a clean rebuild.

并进行干净的重建。

If your real jni glue logic is as trivial as the version presented here, switching to a C version of that could also be an option - but beware that jni syntax is different in C and C++, so you can't just change the file extension.

如果您真正的 jni 粘合逻辑与此处介绍的版本一样微不足道,那么切换到该版本的 C 版本也可能是一种选择 - 但请注意 C 和 C++ 中的 jni 语法不同,因此您不能只更改文件扩展名.

回答by Jessica Cohen

Simply doing your native C++- code between

只需在两者之间执行您的本机 C++- 代码

extern "C" {
    your code
}

Is something that not always will necessarily work - as you can check here.

不一定总是有效的东西 - 您可以在此处查看

Try adding to the Android.mk file:

尝试添加到 Android.mk 文件:

LOCAL_ALLOW_UNDEFINED_SYMBOLS := true

Here you find further infoabout it.

在这里您可以找到有关它的更多信息