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

时间:2022-11-06 09:35:56

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函数进行调用,并将其结果返回Java作为jstring:

#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。可代码:

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)中定义的函数定义。我想这可能是我的安卓系统的一个问题。可文件。

Could anyone tell me what am I doing wrong here?

有人能告诉我我在这里做错了什么吗?

2 个解决方案

#1


31  

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++,您的问题很可能是名称管理。基本上,您需要告诉c++编译器,您试图调用的函数是由C编译器创建的,而不是c++编译器创建的,因此没有将参数类型代码嫁接到它的名称上。现在它还不知道,所以尝试用c++风格的修饰名来调用函数,它与linker实际可用的函数的纯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 glue逻辑与本文给出的版本一样简单,那么切换到C版本也可以是一种选择——但是要注意,在C和c++中jni语法是不同的,所以您不能只更改文件扩展名。

#2


16  

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。可文件:

LOCAL_ALLOW_UNDEFINED_SYMBOLS := true

Here you find further info about it.

在这里你可以找到更多的信息。

#1


31  

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++,您的问题很可能是名称管理。基本上,您需要告诉c++编译器,您试图调用的函数是由C编译器创建的,而不是c++编译器创建的,因此没有将参数类型代码嫁接到它的名称上。现在它还不知道,所以尝试用c++风格的修饰名来调用函数,它与linker实际可用的函数的纯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 glue逻辑与本文给出的版本一样简单,那么切换到C版本也可以是一种选择——但是要注意,在C和c++中jni语法是不同的,所以您不能只更改文件扩展名。

#2


16  

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。可文件:

LOCAL_ALLOW_UNDEFINED_SYMBOLS := true

Here you find further info about it.

在这里你可以找到更多的信息。