【问题标题】:Android NDK / JNI - undefined reference to function defined in custom header fileAndroid NDK / JNI - 对自定义头文件中定义的函数的未定义引用
【发布时间】:2014-04-05 05:37:21
【问题描述】:

使用 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 文件中的问题。

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

【问题讨论】:

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


    【解决方案1】:

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

    但是,由于您混合使用 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++ 中是不同的,因此您不能只是更改文件扩展名。

    【讨论】:

    • 是的,你对这个答案很满意!
    【解决方案2】:

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

    extern "C" {
        your code
    }
    

    某些东西不一定总是有效 - 您可以查看here

    尝试添加到 Android.mk 文件中:

    LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
    

    在这里你可以找到更多关于它的info

    【讨论】:

    • 也许,但有风险。这将掩盖问题,直到运行时。但如果此时不能解决,程序就会崩溃。
    • @ChrisStratton - 感谢您的评论。还有其他建议吗?
    • 是的,考虑到 C/C++ 拆分,这可能是名称修改问题。
    • 缺少什么 .so ?未找到的函数不在库中,它在正在构建的文件之一中。请不要只是从其他来源借用答案而不花时间了解它们是否适用。
    • @ChrisStratton - 好的。我现在明白了。谢谢!刚刚编辑了我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-26
    • 2018-02-24
    相关资源
    最近更新 更多