`

用JNI进行java编程

    博客分类:
  • Java
JNI 
阅读更多

(摘自 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了,应该获得下列结果:

        intMethod: 25
        booleanMethod: false
        stringMethod: JAVA
        intArrayMethod: 33
分享到:
评论

相关推荐

    用jni进行java编程.doc

    用jni进行java编程

    [JAVA]使用JNI技术实现JAVA程序调用dll

    [JAVA]使用JNI技术实现JAVA程序调用dll、[JAVA]使用JNI技术实现JAVA程序调用dll

    利用JNI实现Java调用C++库

    利用JNI技术实现Java中调用C++编写的函数库示例程序源码,并附上参考JNI文档。 详情见本人博客:Java学习之通过JNI调用C/C++编写的dll链接库(图文教程)(http://write.blog.csdn.net/postlist)

    visual studio 2019下C++通过JNI调用JAVA代码

    visual studio 2019下C++通过JNI调用JAVA代码,实现一个简单的打印输出!!!

    用JNI实现java和C++的相互调用

    用JNI实现java和C++的相互调用,内容也就是这个,简单的入门程序,当作一个学习的开端吧

    Java程序中JNI的编程指南

    本书介绍了JNI的设计思想,对这种思想的理解是使用JNI的各种特性的基础。 本书有一部分是JAVA2平台上面的JNI特征的规范说明。JNI程序员可以把这部分用作一个手册。JVM开发者在实现虚拟机的时候必须遵守这些规范。 ...

    使用JNI进行混合编程:在Java中调用C/C++本地库

    NULL 博文链接:https://conkeyn.iteye.com/blog/1597188

    如何利用JNI实现Java插件开发

    本文主要工作在于利用JNI实现对已经完成的视频镜头提取C++程序的调用。  整个过程如下所示:  (1)将视频特征提取算法建立相应的windows下的Dll和Linux下的So(这个两个文件大家都知是什么了吧)  (2)利用jni...

    jni编程c回调java的方法

    jni编程c回调java的方法

    JAVA通过JNI调用C#dll的整个项目工程

    本资源包括JAVA工程,C++工程,C#dll测试工程

    Java本地接口(JNI)编程指南和规范

    Java本地接口(JNI)编程指南和规范英文版翻译

    Java使用JNI测试程序

    博文配套的JNI测试程序,测试Java调用C++的DLL库,详情见文章https://blog.csdn.net/xinxin_2011/article/details/85006113

    Android JNI多线程编程回调JAVA函数

    通过JNI接口静态注册的native方法去创建线程,同时提供native回调Java的方法。通过这个框架可以去实现线程监听某一个状态,然后回调Java的方法(如发消息去通知顶层,实现显示)

    Java JNI 编程进阶

    JNI技术只是针对一些严重影响Java性能的代码段,该部分可能只占源程序的极少部分,所以几乎可以不考虑该部分代码在主流平台之间移植的工作量。同时,也不必过分担心类型匹配问题,我们完全可以控制代码不出现这种...

    JNI--java调用不同平台的动态链接库,dll,so,完美,全教程

    我们知道,使用 JNI 调用 .dll/.so 共享类库是非常非常麻烦和痛苦...使用 JNA ,不需要再编写适配用的 .dll/.so ,只需要在 Java 中编写一个接口和一些代码,作为 .dll/.so 的代理,就可以在 Java 程序中调用 dll/so 。

    jni使用基础,java调用c

    android,使用jni,java调用c代码程序示例。

    JNI快速实现入门(java调用C++程序的方法)

    JNI是java调用C++程序的一种实现方法,网上有一些相关的资料,但不一定能适用,这个文档我在学习JNI时综合网上资料总结的,本人亲测能够实现,希望下载的网友有什么问题多多反馈,希望对学习JNI的朋友有所帮助

    JNI实例 Java调用DLL c++调用Java

    该Demo有两个主要的例子,一个实现的是在java程序中调用DLL中的方法;而一个则是讲述如何在C++代码中调用Java类中的方法、详细阐述了JNI机制的使用,是一个很好的学习例子。

    JNI编程指南书

    JNI是JAVA平台的一个重要特征,使用它我们可以重用以前用C/C++写的大量代码。本书既是一个编程指南也是一个JNI手册。本书共包括三部分: 1、 第二章通过一个简单的例子介绍了JNI。它的对象是对JNI不熟悉的初学者。 2...

    JAVA使用JNI读写INI文件

    JAVA使用JNI读写INI文件的实例。 JAVA本身并没有读写INI文件的现成方法,有些人自己编写方法来读写INI文件,但是这样的方法或多或少的存在着一些问题。...通过此例子程序再进行推敲就可以对JAVA用JNI调用API的功能。

Global site tag (gtag.js) - Google Analytics