(摘自 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编程
[JAVA]使用JNI技术实现JAVA程序调用dll、[JAVA]使用JNI技术实现JAVA程序调用dll
利用JNI技术实现Java中调用C++编写的函数库示例程序源码,并附上参考JNI文档。 详情见本人博客:Java学习之通过JNI调用C/C++编写的dll链接库(图文教程)(http://write.blog.csdn.net/postlist)
visual studio 2019下C++通过JNI调用JAVA代码,实现一个简单的打印输出!!!
用JNI实现java和C++的相互调用,内容也就是这个,简单的入门程序,当作一个学习的开端吧
本书介绍了JNI的设计思想,对这种思想的理解是使用JNI的各种特性的基础。 本书有一部分是JAVA2平台上面的JNI特征的规范说明。JNI程序员可以把这部分用作一个手册。JVM开发者在实现虚拟机的时候必须遵守这些规范。 ...
NULL 博文链接:https://conkeyn.iteye.com/blog/1597188
本文主要工作在于利用JNI实现对已经完成的视频镜头提取C++程序的调用。 整个过程如下所示: (1)将视频特征提取算法建立相应的windows下的Dll和Linux下的So(这个两个文件大家都知是什么了吧) (2)利用jni...
jni编程c回调java的方法
本资源包括JAVA工程,C++工程,C#dll测试工程
Java本地接口(JNI)编程指南和规范英文版翻译
博文配套的JNI测试程序,测试Java调用C++的DLL库,详情见文章https://blog.csdn.net/xinxin_2011/article/details/85006113
通过JNI接口静态注册的native方法去创建线程,同时提供native回调Java的方法。通过这个框架可以去实现线程监听某一个状态,然后回调Java的方法(如发消息去通知顶层,实现显示)
JNI技术只是针对一些严重影响Java性能的代码段,该部分可能只占源程序的极少部分,所以几乎可以不考虑该部分代码在主流平台之间移植的工作量。同时,也不必过分担心类型匹配问题,我们完全可以控制代码不出现这种...
我们知道,使用 JNI 调用 .dll/.so 共享类库是非常非常麻烦和痛苦...使用 JNA ,不需要再编写适配用的 .dll/.so ,只需要在 Java 中编写一个接口和一些代码,作为 .dll/.so 的代理,就可以在 Java 程序中调用 dll/so 。
android,使用jni,java调用c代码程序示例。
JNI是java调用C++程序的一种实现方法,网上有一些相关的资料,但不一定能适用,这个文档我在学习JNI时综合网上资料总结的,本人亲测能够实现,希望下载的网友有什么问题多多反馈,希望对学习JNI的朋友有所帮助
该Demo有两个主要的例子,一个实现的是在java程序中调用DLL中的方法;而一个则是讲述如何在C++代码中调用Java类中的方法、详细阐述了JNI机制的使用,是一个很好的学习例子。
JNI是JAVA平台的一个重要特征,使用它我们可以重用以前用C/C++写的大量代码。本书既是一个编程指南也是一个JNI手册。本书共包括三部分: 1、 第二章通过一个简单的例子介绍了JNI。它的对象是对JNI不熟悉的初学者。 2...
JAVA使用JNI读写INI文件的实例。 JAVA本身并没有读写INI文件的现成方法,有些人自己编写方法来读写INI文件,但是这样的方法或多或少的存在着一些问题。...通过此例子程序再进行推敲就可以对JAVA用JNI调用API的功能。