jni中c和c++实现接口的区别

106 阅读2分钟

jni中c和c++实现接口的区别

一个简单的例子

C版本

JNIEXPORT jstring
JNICALL
Java_com_x_video_cmd_INativeObject_echoByC(
        JNIEnv* env,
        jobject thiz) {
    const char* ffmpeg_version = av_version_info();
    LOGE("Version","ffmpeg version: %s",ffmpeg_version);
    return (*env)->NewStringUTF(env,ffmpeg_version);
}

C++版本

extern "C"
JNIEXPORT jstring
JNICALL
Java_com_x_video_cmd_INativeObject_echo(
        JNIEnv* env,
        jobject /* this */) {
    const char* ffmpeg_version = av_version_info();
    LOGE("Version","ffmpeg version: %s",ffmpeg_version);
    return env->NewStringUTF( ffmpeg_version);
}

c和c++在语法中不一样

  • c需要用(*env) c++使用env
  • c调用函数需要把env作为参数传进去,因为他是过程语言
  • c++不需要,因为他就是按

jni中遇到的一些小疑问

extern "C" 什么作用

  • extern "C" 是c++关键字
  • 让编译器按c语言规则来编译,不支持name mangling

JNIEXPORT是什么,JNICALL是什么

jni.h中定义的宏

#define JNIIMPORT
#define JNIEXPORT  __attribute__ ((visibility ("default")))
#define JNICALL
  • JNIEXPORT 是一个宏标记,可以让宏能被java看到,可以被调用
  • JNICALL也是一个宏标记,确保函数能够遵循正确的调用约定
    • 参数传递
    • 栈清理
    • 返回值处理

c和c++中的字符串,jni中的字符串

C 中的字符串

  • 表示:在 C 中,字符串通常以字符数组的形式表示,以空字符('\0')结尾。例如:char str[] = "Hello";
  • 操作:C 提供了标准库函数来处理字符串,如 strcpy()strlen()strcat() 等。
  • 内存管理:在 C 中,处理字符串时需要手动管理内存,特别是在动态分配字符串时。使用 malloc()free() 进行内存分配和释放。

C++ 中的字符串

  • 表示:C++ 提供了 std::string 类来处理字符串,这对内存管理和字符串操作提供了更高层次的封装。
  • 操作std::string 支持多种操作,如连接(+)、比较(==)、查找(find())等,而且这些操作通常更安全、更直观。
  • 内存管理:使用 std::string 时,内存管理是自动的。字符串对象在销毁时会自动释放其占用的内存。

JNI 中的字符串

  • 表示:JNI 使用 jstring 类型来表示 Java 中的字符串。jstring 是对 Java 字符串的引用。
  • 操作:不能直接操作 jstring。需要使用 JNI 提供的函数将其转换为可操作的格式,如 GetStringUTFChars() 可以将 jstring 转换为 C 风格的字符串(const char*),但需注意编码转换(UTF-8)。
  • 内存管理:在 JNI 中,使用完通过 GetStringUTFChars() 获得的字符串后,必须调用 ReleaseStringUTFChars() 来释放分配的内存。这一点非常重要,否则可能导致内存泄漏。

char * string 和jstring 的转化

char* -> jstring

const char *nativeString = "Hello from C!"; 
jstring result = (*env)->NewStringUTF(env,nativeString);

jstring -> char*

const char *nativeString = (*env)->GetStringUTFChars(env, jStr, 0);

(*env)->ReleaseStringUTFChars(env, jStr, nativeString);

char * -> std::string

const char* cstr = "Hello, World!";
std::string str(cstr);

std::string -> char*

std::string str = "Hello, World!"; 
const char* cstr = str.c_str();

jstring <-> std::string

一般先转成char* 在用char*转成string