当我们开始接触JNI但是还不熟悉的时候,也许会这样几个问题:
- Java程序和native程序的数据类型通常是不一样的,它们怎么相互映射的呢?
- 怎么在native方法中访问java方法传递过来的数据呢?
- 在native方法中可以创建java对象吗?
- 如何把结果返回给调用它的java方法?
读完本文你将会明白如上问题的来龙去脉。首先我在重复一下如何编写JNI相关的应用程序,我们必须在java方法中声明一个native的方法,比如 public native String getLine(String prompt);这个方法具有的两个特点是,引入了关键字native,它的意思是这个方法的实现由其他的语言实现,比如c/c++等。另外这个方法是以 分号结尾的,表明这个方法不包括实现。我们在上篇文章已经知道使用javah命令可以得到我们需要的header文件。下面给出java程序和相关的.h 文件的代码
//Prompt.java
class Prompt {
private native String getLine(String prompt);
public static void main(String args[]) {
Prompt p = new Prompt();
String input = p.getLine("Type a line: ");
System.out.println("User typed: " + input);
}
static {
System.loadLibrary("prompt");
}
}
//Prompt.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Prompt */
#ifndef _Included_Prompt
#define _Included_Prompt
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Prompt
* Method: getLine
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_Prompt_getLine
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
我们可以看到在Prompt.h文件中定义了我们要实现的函数的原型,我们主要关心两点一个是方法名称另一个是方法的参数,方法的名称为Java_Prompt_getLine,它是由如下四部分组成
看看方法的参数,由三个参数组成分别是JNIEnv *, jobject, jstring。JNIEnv是一个JNI接口指针,它事实上是由函数表组成的,我们可以使用JNIEnv来访问java对象。jobject是当前类的 的引用,想当与java中的this。最后一个参数是jstring,代表了我们java方法中的String prompt。
在编写native方法的时候,无论是java基本类型还是对象我们都不能在c/c++中直接使用,必须要转成相对应得类型,下面给出基本数据类型的对应关系。
Java Type |
Native Type |
Size in bits |
boolean
|
jboolean
|
8, unsigned |
byte
|
jbyte
|
8 |
char
|
jchar
|
16, unsigned |
short
|
jshort
|
16 |
int
|
jint
|
32 |
long
|
jlong
|
64 |
float
|
jfloat
|
32 |
double
|
jdouble
|
64 |
void
|
void
|
n/a |
关于java对象,JNI都是把它映射为jobject,为了减少编程的错误可能性,同时从jobject中实现了一些子类型,比如jstring等。
下面我们讲述,如何在native方法中访问java方法的参数,如何在native方法中创建java对象。我们必须清楚地知道,在访问java参数的 时候,首先要把它转换为相应的类型,比如参数String prompt在.h文件中为jstring。但是在实现这个方法的时候,我们不能直接对jstring进行操作,因为它与char *是不同的,我们要通过JNIEnv提供的方法把它转换为char *。比如
char buf[128];
const char *str = env->GetStringUTFChars(prompt, 0);
printf("%s", str);
注 意一点,我们必须要主动释放我们得到的char *,否则会造成内存泄漏。释放的方法还是通过JNIenv提供的方法,(*env).ReleaseStringUTFChars(prompt, str);。JNIEnv同样提供了构造String的方法,使得我们可以返回给调用者一个String类型的返回值
gets(buf);
return (*env).NewStringUTF(buf);
下面给出native实现的源代码(c++代码)
#include <stdio.h>
#include <jni.h>
#include "Prompt.h"
JNIEXPORT jstring JNICALL
Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring prompt)
{
char buf[128];
const char *str = env->GetStringUTFChars(prompt, 0);
printf("%s", str);
(*env).ReleaseStringUTFChars(prompt, str);
gets(buf);
return (*env).NewStringUTF(buf);
}
在VC++中,你可以创建一个dll工程,最后把得到的prompt.dll方到Prompt.class的目录,运行java Prompt,系统就会提示你输入一行字符。输入回车后则可以回显到控制台。
分享到:
相关推荐
JNI(Java Native Interface)是Sun Microsystems公司定义的一套标准接口,用于实现Java代码与本地代码(通常是C或C++)之间的交互。随着Java的发展,JNI的重要性日益凸显,因为它允许Java程序调用本地库的功能,...
Java使用JNI(Java Native Interface)测试程序是一种将Java与C++代码集成的技术,它允许Java应用程序直接...通过实践这个测试程序,开发者可以更好地掌握JNI的使用技巧,以便在实际项目中灵活地集成Java和本地代码。
2. **操作系统集成**:JNI允许Java程序直接访问操作系统服务,如文件系统、网络、多线程等。 3. **硬件驱动交互**:当需要与硬件设备交互时,可以编写本地代码并通过JNI调用。 4. **库调用**:如果有一个用其他语言...
4. 集成第三方库:某些第三方库只提供了C/C++接口,使用JNI可以方便地将这些库集成到Java应用中。 三、JNI基本结构 1. Java层:定义本地方法,使用`native`关键字声明,并在类加载时通过`System.loadLibrary`加载...
本笔记主要探讨如何通过JNI实现Java方法与本地(Native)方法的相互调用。 首先,理解JNI的基本结构是至关重要的。JNI接口定义了一组函数,Java代码可以通过这些函数调用本地方法,反之,本地方法也可以通过这些...
在这个“GMSSL的java调用(JNI库和调用实例).zip”压缩包中,我们主要探讨如何在Java环境中通过JNI(Java Native Interface)来调用GMSSL库,以便利用这些国密算法进行数据加解密和哈希运算。 首先,我们需要了解...
使用 JNI 将 Java 应用程序与 C++ DLL 文件集成需要以下步骤:创建一个 Java 工程,生成 `.class` 文件,使用 `javah` 命令生成 `.h` 头文件,创建一个 C++ 工程,并将生成的 `.h` 头文件复制到工程中,编写 C++ ...
总之,"JNI(Java Native Interface)_03"涵盖了JNI的高级用法和实践,对于希望深入理解和使用JNI的开发者来说,这些资源是非常有价值的。通过学习,开发者可以更好地结合Java和本地代码,充分利用两者的优点,解决...
- 实现`本地方法`:在C/C++源文件中实现这些函数,使用JNIEnv指针和JNI函数调用来与Java世界交互。 - 编译和链接:使用NDK(Native Development Kit)将C/C++源文件编译为共享库(`.so`文件)。 - 集成到Android...
这些函数是Java程序与本地代码(C/C++)进行交互的基础,包括`FindClass`用于查找Java类,`GetMethodID`获取Java方法的ID,`NewObject`用于创建Java对象,以及`CallVoidMethod`、`CallIntMethod`等用于调用Java方法...
本话题将深入探讨如何在Android中使用JNI进行多线程编程,并实现native方法对Java函数的回调。 1. **JNI基础知识**: - JNI是Java平台的一部分,为Java应用程序提供了与本地代码交互的能力。开发者可以通过JNI在...
在实际项目中,这种技术常用于混合开发,如利用Java的网络通信库、大数据处理库等,与Delphi的桌面应用或游戏引擎集成。不过,需要注意的是,跨语言调用会带来额外的复杂性,包括类型映射、异常处理和内存管理等问题...
总之,JNI实例“Java调用DLL c++调用Java”是一个实用的学习资源,它详细解释了如何利用JNI进行Java与C++的交互,无论是将本地库引入Java程序还是将Java功能嵌入C++应用。通过实践这些例子,开发者能够深入理解JNI的...
JNI在Java的本地方法接口(Native Method Interface,NMI)基础上发展而来,最初随着Java开发工具包(JDK)1.0发布,后随着Java运行时接口(Java Runtime Interface)的集成,提供了更丰富的原生接口。 JDK1.0时,...
串口通讯JNI集成是将Java语言与C/C++代码通过JNI(Java Native Interface)进行交互,以实现对硬件串口的高效控制。在Android或Java应用程序中,有时我们需要利用底层库来提高性能或访问特定硬件功能,比如串口通信。...
JNI(Java Native Interface)作为Java虚拟机(JVM)的一部分,允许Java应用程序与本地代码交互。这种能力使得Java能够充分利用C/C++的性能优势和丰富的库资源,同时也为跨平台应用提供了可能。通过JNI,Java程序...
JNI(Java Native Interface)是Java平台的一部分,它为Java代码提供了与本地代码(如C++或C)交互的能力。在Java RCP中使用JNI,主要是为了访问特定于平台的功能,提升性能,或者调用已有的本地库。 1. **JNI简介*...
在本例中,我们将详细介绍如何使用 JNI 将 Java 代码与 C/C++ 代码集成,生成动态库,并加载到 Java 程序中。 JNI 概述 JNI 提供了一种机制,允许 Java 代码调用 native 代码,反之亦然。JNI 提供了两种方式来实现...
通过使用Jni,Java程序可以调用操作系统的native接口,实现与native代码的集成。 二、Jni的使用步骤 1. 编写Java类:首先需要编写一个Java类,例如ComputerInfo,该类中包含native方法,例如getCPUSN()。 2. 编译...
JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。在本主题"JNI_JAVA_C++"中,我们将深入探讨如何利用JNI在Java和C++之间实现数据交换,以及调用和实现彼此的函数。...