4

我有一段简单的代码要在我的 java (android) 应用程序中使用:

#include <string.h>
#include <jni.h>

jstring 
Java_com_example_ndk_MainActivity_stringFromJNI( JNIEnv* env,
                                                  jobject thiz)
{
    return (*env)->NewStringUTF(env, "Hello from JNI !");
}

如果我使用 C 并调用此文件 *.c - 一切正常,但我想在 C++ 上使用此代码,我将此文件重命名为 *.cpp(并更改 Android.mk)。一切都已编译,但是当我尝试以我在 C 中使用它的方式使用此函数时,我遇到了错误。

*我还修改了函数的主体:

    return env->NewStringUTF("Hello from JNI !");

尝试使用这个:

public native String stringFromJNI();

static {
    System.loadLibrary("hello-jni");
}

并得到这样的错误:

09-10 17:55:46.410: W/dalvikvm(6339): No implementation found for native Lcom/example/ndk/MainActivity;.stringFromJNI ()Ljava/lang/String;


09-10 17:55:46.410: E/AndroidRuntime(6339): java.lang.UnsatisfiedLinkError: stringFromJNI
09-10 17:55:46.410: E/AndroidRuntime(6339):     at com.example.ndk.MainActivity.stringFromJNI(Native Method)
09-10 17:55:46.410: E/AndroidRuntime(6339):     at com.example.ndk.MainActivity.onCreate(MainActivity.java:22)

我不明白为什么相同的代码在 C 中运行并在 C++ 中失败(运行时)。

4

2 回答 2

19

为了允许函数重载,C++ 使用了一种叫做name mangling的东西。这意味着 C++ 中的函数名称与普通 C 中的函数名称不同。

要禁止此名称修改,您必须将函数声明为extern "C"

extern "C" jstring 
Java_com_example_ndk_MainActivity_stringFromJNI( JNIEnv* env,
                                                 jobject thiz)
{
    return (*env)->NewStringUTF(env, "Hello from JNI !");
}
于 2012-09-10T14:13:12.403 回答
2

在 C++ 代码中使用 C 调用约定,请在函数周围加上:

extern "C" 
{
    /* your C API */
}
于 2012-09-10T14:18:39.697 回答