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

Pin*_*azz 20 c c++ java-native-interface android android-ndk

使用JNI,我正在尝试为Android NDK编写一个本机C++方法,该方法调用自定义头文件中定义的C函数.但是,我的C函数调用收到了一个未定义的引用错误.

这是我的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));
}
Run Code Online (Sandbox Code Playgroud)

这是我的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";
}
Run Code Online (Sandbox Code Playgroud)

这是我的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)
Run Code Online (Sandbox Code Playgroud)

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

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

Chr*_*ton 32

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

但是,由于您正在混合使用C和C++,因此您的问题可能就是名称错误.基本上,您需要告诉C++编译器您尝试调用的函数是由C编译器而不是C++编译器创建的,因此没有将参数类型代码移植到其名称上.现在它不知道,所以试图通过C++样式修饰的名称调用该函数,该名称不同于链接器实际可用的函数的普通C名称.

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

#ifdef __cplusplus
extern "C" {
#endif
Run Code Online (Sandbox Code Playgroud)

最后这个

#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)

并做一个干净的重建.

如果您真正的jni glue逻辑与此处提供的版本一样简单,那么切换到它的C版本也可以是一个选项 - 但要注意jni语法在C和C++中是不同的,因此您不能只更改文件扩展名.


Jes*_*hen 17

简单地做你的原生C++ - 之间的代码

extern "C" {
    your code
}
Run Code Online (Sandbox Code Playgroud)

是不是总能发挥作用的东西 - 你可以在这里查看.

尝试添加到Android.mk文件:

LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
Run Code Online (Sandbox Code Playgroud)

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

  • 也许,但有风险.这将掩盖问题直到运行时.但如果在那时无法解决,程序将崩溃. (2认同)