使用 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));
}
这是我的 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";
}
这是我的 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)
显然,似乎没有找到自定义头文件( gesture_detector.h
)中定义的函数定义。我认为这可能是我的 Android.mk 文件中的问题。
谁能告诉我我在这里做错了什么?
原文由 Pink Jazz 发布,翻译遵循 CC BY-SA 4.0 许可协议
“未定义的引用”错误来自 _链接器_。你的头文件只满足编译器。
但是,由于您将 C 和 C++ 混合使用,因此您的问题可能是 name mangling 。基本上,您需要告诉 C++ 编译器您尝试调用的函数是由 C 编译器而不是 C++ 编译器创建的,因此没有将参数类型代码移植到其名称上。现在它不知道这一点,因此尝试通过 C++ 样式的修饰名称调用函数,该名称与链接器实际可用的函数的纯 C 名称不同。
在你的gesture_detector.h文件的开头添加这个:
最后是这个
并进行干净的重建。
如果您真正的 jni 胶合逻辑与此处介绍的版本一样微不足道,那么切换到 C 版本也可能是一种选择 - 但请注意 jni 语法在 C 和 C++ 中不同,因此您不能只更改文件扩展名.