(摘自 IBM DW)
JNI ( Java Native Interface) 是一个本机编程接口,它是 Java 软件开发工具箱( Java Software Development Kit (SDK) )的一部分。 JNI 允许 Java 代码使用以其它语言(譬如 C 和 C++ )编写的代码和代码库。 Invocation API ( JNI 的一部分)可以用来将 Java 虚拟机( JVM )嵌入到本机应用程序中,从而允许程序员从本机代码内部调用 Java 代码。当无法用 Java 语言编写整个应用程序时, JNI 允许您使用本机代码。在下列典型情况下,您可能决定使用本机代码:
- 希望用更低级、更快的编程语言去实现对时间有严格要求的代码。
- 希望从 Java 程序访问旧代码或代码库。
- 需要标准 Java 类库中不支持的依赖于平台的特性。
步骤 1 :编写 Java 代码
public class Sample1 {
public native int intMethod(int n);
public native boolean booleanMethod(boolean bool);
public native String stringMethod(String text);
public native int intArrayMethod(int [] intArray);
public static void main(String[] args) {
System.loadLibrary ("Sample1");
Sample1 sample = new Sample1();
int square = sample.intMethod(5);
boolean bool = sample.booleanMethod(true );
String text = sample.stringMethod("JAVA");
int sum = sample.intArrayMethod(new int [] { 1, 1, 2, 3, 5, 8, 13 });
System.out .println("intMethod: " + square);
System.out .println("booleanMethod: " + bool);
System.out .println("stringMethod: " + text);
System.out .println("intArrayMethod: " + sum);
}
}
步骤 2 :创建 C/C++ 头文件
执行如下命令:
javah Sample1
生成文件内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Sample1 */
#ifndef _Included_ Sample1
#define _Included_ Sample1
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Sample1
* Method: intMethod
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_ Sample1_intMethod
(JNIEnv *, jobject, jint);
/*
* Class: Sample1
* Method: booleanMethod
* Signature: (Z)Z
*/
JNIEXPORT jboolean JNICALL Java_ Sample1_booleanMethod
(JNIEnv *, jobject, jboolean);
/*
* Class: Sample1
* Method: stringMethod
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_ Sample1_stringMethod
(JNIEnv *, jobject, jstring);
/*
* Class: Sample1
* Method: intArrayMethod
* Signature: ([I)I
*/
JNIEXPORT jint JNICALL Java _Sample1_intArrayMethod
(JNIEnv *, jobject, jintArray);
#ifdef __cplusplus
}
#endif
#endif
头文件中 JNIEXPORT 和 JNICALL 是用于导出函数的、依赖于编译器的指示符。返回类型是映射到 Java 类型的 C/C++ 类型。除了 Java 声明中的一般参数以外,所有这些函数的参数表中都有一个指向 JNIEnv 和 jobject 的指针。
指向 JNIEnv 的指针实际上是一个指向函数指针表的指针。这些函数提供各种用来在 C 和 C++ 中操作 Java 数据的能力。jobject 参数引用当前对象。因此,如果 C 或 C++ 代码需要引用 Java 函数,则这个 jobject 充当引用或指针,返回调用的 Java 对象。
函数名本身是由前缀 “Java_” 加全限定类名,再加下划线和方法名构成的。
步骤 3 :编写 C/C++ 代码 , 创建共享库文件
编写 C/C++ 函数实现时,有一点需要牢记:说明必须和 Sample1.h 的函数声明完全一样。
C 实现 Sample1.c
#include "Sample1.h"
#include <string.h>
JNIEXPORT jint JNICALL Java_Sample1_intMethod
(JNIEnv *env, jobject obj, jint num) {
return num * num;
}
JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
(JNIEnv *env, jobject obj, jboolean boolean) {
return !boolean;
}
JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
(JNIEnv *env, jobject obj, jstring string) {
const char *str = (*env)->GetStringUTFChars(env, string, 0);
char cap[128];
strcpy(cap, str);
(*env)->ReleaseStringUTFChars(env, string, str);
return (*env)->NewStringUTF(env, strupr(cap));
}
JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
(JNIEnv *env, jobject obj, jintArray array) {
int i, sum = 0;
jsize len = (*env)->GetArrayLength(env, array);
jint *body = (*env)->GetIntArrayElements(env, array, 0);
for (i=0; i<len; i++)
{ sum += body[i];
}
(*env)->ReleaseIntArrayElements(env, array, body, 0);
return sum;
}
void main(){}
C++ 实现 Sample1.cpp
#include "Sample1.h"
#include <string.h>
JNIEXPORT jint JNICALL Java_Sample1_intMethod
(JNIEnv *env, jobject obj, jint num) {
return num * num;
}
JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
(JNIEnv *env, jobject obj, jboolean boolean) {
return !boolean;
}
JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
(JNIEnv *env, jobject obj, jstring string) {
const char *str = env->GetStringUTFChars(string, 0);
char cap[128];
strcpy(cap, str);
env->ReleaseStringUTFChars(string, str);
return env->NewStringUTF(strupr(cap));
}
JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
(JNIEnv *env, jobject obj, jintArray array) {
int i, sum = 0;
jsize len = env->GetArrayLength(array);
jint *body = env->GetIntArrayElements(array, 0);
for (i=0; i<len; i++)
{ sum += body[i];
}
env->ReleaseIntArrayElements(array, body, 0);
return sum;
}
void main(){}
C 和 C++ 函数实现的比较
C 和 C++ 代码几乎相同;唯一的差异在于用来访问 JNI 函数的方法。在 C 中, JNI 函数调用由“ (*env)-> ”作前缀,目的是为了取出函数指针所引用的值。在 C++ 中, JNIEnv 类拥有处理函数指针查找的内联成员函数。下面将说明这个细微的差异,其中,这两行代码访问同一函数,但每种语言都有各自的语法。
C 语法: jsize len = (*env)->GetArrayLength(env,array);
C++ 语法: jsize len =env->GetArrayLength(array);
用来创建共享库文件的命令取决于您使用的编译器。下面是在 Windows 系统上执行的命令。
Windows : cl -Ic:\jdk\include -Ic:\jdk\include\win32 -LD Sample1.c -FeSample1.dll
完成以上步骤后,就可以运行Java程序Sample1了,应该获得下列结果:
stringMethod: JAVA
intArrayMethod: 33
相关推荐
总结,JNI(Java Native Interface)允许我们在 Java 程序中调用 C/C++ 代码,以利用其性能优势或访问特定平台的功能。这个过程包括编写 Java 代码声明 native 方法,编译 Java 代码,生成 C/C++ 头文件,实现 C/C++...
- **灵活性**:通过JNI,开发者可以灵活地选择使用Java或本地代码,从而能够在需要高性能处理的地方使用C/C++,而在需要动态性和跨平台能力的地方使用Java。 - **兼容性**:由于JNI是一个标准接口,因此一旦实现了...
JNI在Android开发中尤其重要,因为Android系统的主要编程语言是Java,但为了实现高性能计算或调用操作系统底层功能,开发者常会使用C/C++编写部分代码。 首先,要使用JNI创建Java对象,你需要定义一个Java类并添加...
在本文中,我们将深入探讨如何在Visual Studio 2019环境下使用C++通过Java Native Interface (JNI)来调用Java代码。JNI是Java平台的一部分,它为Java应用程序提供了与本地代码交互的能力,使得开发者可以将Java应用...
Java Native Interface(JNI)是Java平台的标准组成部分,它允许Java代码和其他语言写的代码进行交互。JNI在许多场景下非常有用,比如需要利用已有的C/C++库,或者提高程序的性能,因为本地代码通常可以更高效地执行...
JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。C# DLL是用C#编译的动态链接库,可以提供特定的功能或服务。在本项目工程中,Java应用会通过JNI来调用C# DLL中的...
描述 "code for my blog" 表明这是一个博客文章的源代码,作者可能详细解释了如何在Java程序中使用JNI来处理温度相关的问题,例如读取传感器数据、进行复杂计算或者优化性能。通常,这样的博客会涵盖以下几点: 1. ...
本话题将深入探讨如何在Android中使用JNI进行多线程编程,并实现native方法对Java函数的回调。 1. **JNI基础知识**: - JNI是Java平台的一部分,为Java应用程序提供了与本地代码交互的能力。开发者可以通过JNI在...
这是一项技术性很强的任务,需要对C++编程、Java虚拟机的工作原理以及JNI接口有深入的理解。 首先,Java虚拟机(JVM)是Java平台的核心组成部分,它负责执行Java字节码。C++创建JVM的过程主要分为以下几步: 1. **...
最后,为了在Delphi程序中使用这个DLL,我们需要将其加载到内存中,并通过JNI接口调用Java函数。这可以通过`LoadLibrary`和`GetProcAddress`等API来实现。 总结来说,Delphi 10.3通过JNI调用Java函数的过程涉及以下...
理解JNI的工作原理,掌握如何声明和实现native方法,以及如何在本地代码中调用Java方法,对于进行系统级编程和优化Java应用至关重要。在实际开发中,开发者应根据需求选择合适的方法,合理利用JNI,以提高程序的性能...
JNI是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。JNI接口提供了在本地代码中创建、访问和修改Java对象的方法,使得开发者可以将C/C++或者Delphi等本地代码嵌入到Java应用程序中。 要实现...
使用JNI,Java程序可以调用GMSSL库进行SM3哈希计算,适用于数据完整性校验和数字签名的摘要生成。 3. **SM4算法**:SM4是一种对称分组密码算法,用于块加密。它具有128位的密钥和块大小,与AES相似。通过JNI,我们...
JNI在Java编程中起到了重要的作用,尤其是在处理性能敏感的代码段、本地平台接口调用以及嵌入式开发场景时。以下是关于Java JNI编程进阶的详细说明: 1. **性能优化**: - Java的平台无关性使其成为企业级应用的...
Java Native Interface (JNI) 是Java平台的一项强大特性,允许应用程序结合使用C、C++等其他编程语言编写的本地代码以及Java语言代码。这一功能让程序员能够在利用Java平台优势的同时,不必舍弃对遗留代码的投资。...
在Java编程环境中,有时我们需要利用C或C++的高性能特性,这时可以借助Java Native Interface (JNI) 进行Java和C++之间的交互调用。JNI允许Java代码调用本地(非Java)代码,并且反之亦然。下面我们将详细介绍如何用...
Java使用JNI(Java Native Interface)测试程序是一种将Java与C++代码集成的技术,它允许Java应用程序直接调用本地(非Java)代码,如C++编写的动态链接库(DLL)。在本示例中,我们看到的是一个用于演示如何通过JNI...
在这个场景中,你提到的是使用JNI在VS2013环境下,将Java与C++进行互调。 首先,让我们了解一下JNI的基本工作原理: 1. **定义Java方法:** 在Java类中,你需要声明一个native方法,这意味着它的实现将在本地代码...
JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码与其他语言写的代码进行交互。JNI在Java与本地代码之间提供了一个桥梁,使得Java可以调用本地库中的函数,同时也允许本地代码实例化Java对象并...
总之,JNI实例“Java调用DLL c++调用Java”是一个实用的学习资源,它详细解释了如何利用JNI进行Java与C++的交互,无论是将本地库引入Java程序还是将Java功能嵌入C++应用。通过实践这些例子,开发者能够深入理解JNI的...