Android NDK/JNI - 对自定义头文件中定义的函数的 undefined reference

标签 android c++ c android-ndk java-native-interface

使用 JNI,我正在尝试为 Android NDK 编写 native C++ 方法,该方法调用自定义头文件中定义的 C 函数。但是,我的 C 函数调用出现 undefined reference 错误。

这是我的 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 文件中的问题。

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

最佳答案

“ undefined reference ”错误来自 链接器。你的头文件只满足编译器。

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

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

#ifdef __cplusplus
extern "C" {
#endif

最后是这个

#ifdef __cplusplus
}
#endif

然后进行干净的重建。

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

关于Android NDK/JNI - 对自定义头文件中定义的函数的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22159183/

相关文章:

c - 即使使用 fflush 也会跳过 scanf

c++ - 不存在合适的构造函数可从 "uint8_t *"转换为 "std::vector<uint8_t, std::allocator<uint8_t>>"

c++ - 从 int64 转换为字节数组

在有向图中循环

c - 使用 Win32 API 将自定义边框添加到另一个应用程序

c++ - 用于 Linux 上 C++ 的带有 GUI 的调试器

android - 展示如何使用 Android ID 认证的示例代码

无法识别 android 谷歌地图导入

android - 在 Android 应用程序中从 http 转换为 https 后出现 SocketTimeoutException

android - 如何为 View 的翻译设置动画