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.
在这里你可以找到更多的信息。