JAVA JNI函数的注册过程详细介绍

JNI(Java Native Interface)是Java向底层语言(如C、C++)展示其本地方法(Native Method)能力的桥梁,因此在使用JNI时需要将Java方法与本地C/C++函数进行关联,这便是JNI函数的注册过程。

JNI函数的注册流程如下:

1.在C/C++文件中,定义实现Java方法的本地函数。

2.使用javah命令生成与本地函数对应的头文件。

3.在头文件中声明该本地函数为extern "C"类型。

4.使用JNI_OnLoad()函数将该本地函数通过RegisterNatives()函数进行注册。

下面是两条示例说明:

示例一

我们想要在Java中调用一个用C实现的方法,该方法的函数原型为:

void print_str(const char* str);

C中的实现方式如下:

#include <jni.h>

void print_str(const char* str)
{
    printf("%s", str);
}

在Java中调用该方法的代码为:

public class NativeCodeDemo {
    static {
        System.loadLibrary("print_str");
    }

    // Native方法
    private static native void printStr(String str);

    public static void main(String[] args) {
        NativeCodeDemo.printStr("Hello World");
    }
}

然后使用javah命令生成头文件NativeCodeDemo.h

javah -classpath ./ NativeCodeDemo

生成的头文件如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class NativeCodeDemo */

#ifndef _Included_NativeCodeDemo
#define _Included_NativeCodeDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     NativeCodeDemo
 * Method:    printStr
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_NativeCodeDemo_printStr
  (JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}
#endif
#endif

在头文件中,print_str函数被声明为JNIEXPORT void JNICALL类型。

接下来,在C中定义一个JNI_OnLoad函数,该函数将该本地函数通过RegisterNatives()函数进行注册,代码如下:

#include <jni.h>
#include "NativeCodeDemo.h"

void print_str(const char* str)
{
    printf("%s", str);
}

JNIEXPORT void JNICALL Java_NativeCodeDemo_printStr
  (JNIEnv *env, jclass clazz, jstring str)
{
    const char* cstr = (*env)->GetStringUTFChars(env, str, NULL);
    print_str(cstr);
    (*env)->ReleaseStringUTFChars(env, str, cstr);
}

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
    JNIEnv *env;
    jclass clazz;
    if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_8) != JNI_OK) {
        return JNI_ERR;
    }
    clazz = (*env)->FindClass(env, "NativeCodeDemo");
    if (clazz == NULL) {
        return JNI_ERR;
    }
    const JNINativeMethod methods[] = {
        {"printStr", "(Ljava/lang/String;)V", (void *)&Java_NativeCodeDemo_printStr},
    };
    if ((*env)->RegisterNatives(env, clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
        return JNI_ERR;
    }
    return JNI_VERSION_1_8;
}

示例二

我们想在Java中调用一个用C++实现的函数,该函数的函数原型为:

int add(int a, int b);

我们可以定义一个类MyMath,该类中的成员方法int add(int, int)用C++实现:

#include <jni.h>

class MyMath {
public:
    static int add(int a, int b) {
        return a + b;
    }
};

然后在Java文件中,定义一个native方法,将其与MyMath类中实现的add方法关联:

public class MyMath {
    static {
        System.loadLibrary("my-math");
    }

    // Native方法
    private static native int add(int a, int b);

    // 测试方法
    public static void main(String[] args) {
        int result = MyMath.add(4, 6);
        System.out.println(result);
    }
}

使用javah命令生成头文件MyMath.h

javah -classpath ./ MyMath

生成的头文件如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MyMath */

#ifndef _Included_MyMath
#define _Included_MyMath
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     MyMath
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_MyMath_add
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

在头文件中,add函数被声明为JNIEXPORT jint JNICALL类型。

定义实现该函数的C++代码如下:

#include <jni.h>
#include "MyMath.h"

class MyMath {
public:
    static int add(int a, int b) {
        return a + b;
    }
};

JNIEXPORT jint JNICALL Java_MyMath_add(JNIEnv *env, jclass clazz, jint a, jint b)
{
    return MyMath::add(a, b);
}

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
    JNIEnv *env;
    jclass clazz;
    if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_8) != JNI_OK) {
        return JNI_ERR;
    }
    clazz = (*env)->FindClass(env, "MyMath");
    if (clazz == NULL) {
        return JNI_ERR;
    }
    const JNINativeMethod methods[] = {
        {"add", "(II)I", (void *)&Java_MyMath_add},
    };
    if ((*env)->RegisterNatives(env, clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
        return JNI_ERR;
    }
    return JNI_VERSION_1_8;
}

以上就是Java JNI函数的注册过程的详细攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JAVA JNI函数的注册过程详细介绍 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • 使用IDEA配置Tomcat和连接MySQL数据库(JDBC)详细步骤

    以下是使用IDEA配置Tomcat和连接MySQL数据库(JDBC)详细步骤: 配置Tomcat 步骤1:下载Tomcat 首先,我们需要下载Tomcat。可以在Tomcat官网下载。下载完成后,将Tomcat压缩包解压到本地合适的目录。 步骤2:在IDEA中添加Tomcat服务器 1.打开IDEA,进入File -> Settings -> B…

    Java 2023年5月20日
    00
  • Java实现JDBC连接数据库简单案例

    下面我将详细讲解Java实现JDBC连接数据库简单案例的完整攻略。 第一步:导入JDBC驱动 JDBC驱动包可以从官网下载,下载完成后需要将其导入到项目中。导入方式有两种,分别是将其放入CLASSPATH中或者将其直接加入项目中,本文采用第二种方式。 第二步:建立数据库连接 在Java中使用JDBC驱动连接数据库,需要调用驱动程序提供的DriverManag…

    Java 2023年5月19日
    00
  • java时区转换的理解及示例详解

    Java时区转换的理解及示例详解 什么是时区 时区(Time Zone),又称作区时,是因为地球是一个球体,而地球又不停地自转和公转的结果,使得地球的不同地区同一时刻看到的太阳高度角不同。地球表面被分为24个正负时区,本初子午线所在的地区是格林威治标准时间,标志着世界统一时间的起点,中国属于东八区,与标准时间差8个小时。 如何在Java程序中进行时区转换 J…

    Java 2023年5月20日
    00
  • Json字符串与Object、List、Map的互转工具类

    介绍:在Java中,经常会使用Json格式的字符串来传输数据,但是在Java程序内部我们又需要把Json字符串转换为Java对象来方便的操作数据。本文将介绍如何使用Json相关的工具类将Json字符串转换为Java对象,并将Java对象转换为Json格式的字符串。 将Json字符串转换为Java对象 当我们有一个Json格式的字符串需要转换为Java对象时,…

    Java 2023年5月26日
    00
  • Velocity基本语法介绍

    Velocity基本语法介绍 Velocity是一种模板引擎,它提供了一套简单易用的模板语言,用于生成动态的Web页面、邮件等。下面是Velocity的基本语法介绍。 变量 Velocity中的变量使用${}包裹。可以将变量放置在文本、HTML标签、JavaScript代码片段等任何地方。例如: 欢迎光临${shopName}网站 ${shopName}这个…

    Java 2023年6月15日
    00
  • 详解JAVA Spring 中的事件机制

    详解JAVA Spring 中的事件机制 事件机制 Java Spring框架中的事件机制基于观察者模式实现,核心概念包括: 事件(Event): 表示一个操作或状态的变更,通常是一个类或一个接口; 事件源(Event Source): 触发事件的对象,通常是一个类或一个接口; 应用程序监听器(Application Listener): 监听事件的组件,通…

    Java 2023年5月19日
    00
  • java实现自定义日期选择器的方法实例

    下面我来详细讲解“java实现自定义日期选择器的方法实例”的完整攻略。本攻略分为以下几个部分: 1. 准备工作 在开始实现日期选择器之前,我们需要先准备一些工作。 添加依赖 在项目的gradle文件中,我们需要添加以下依赖: implementation ‘com.squareup.timessquare:library:1.6.5’ 创建布局文件 接着,我…

    Java 2023年5月20日
    00
  • java版微信公众平台消息接口应用示例

    首先,我们需要明确,本攻略是针对Java版的微信公众平台消息接口应用示例。下面,我将详细讲解Java版微信公众平台消息接口应用示例的完整攻略。 环境准备 在开始开发前,首先需要准备好以下环境: Java JDK 1.8及以上 Apache Maven Eclipse或其他Java开发IDE 项目创建 在IDE中创建一个Maven项目,选择纯Java项目,并添…

    Java 2023年6月16日
    00
合作推广
合作推广
分享本页
返回顶部