Java JNI浅析(一)
生活随笔
收集整理的這篇文章主要介紹了
Java JNI浅析(一)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
JNI是Java Native Interface的 縮寫。從Java 1.1開始,Java Native Interface (JNI)標(biāo)準(zhǔn)成為java平臺(tái)的一部分,它允許Java代碼和其他語言寫的代碼進(jìn)行交互。JNI一開始是為了本地已編譯語言,尤其是C和C++而設(shè)計(jì) 的,但是它并不妨礙你使用其他語言,只要調(diào)用約定受支持就可以了。
??? 使用java與本地已編譯的代碼交互,通常會(huì)喪失平臺(tái)可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的,比如,使用一些舊的庫,與硬件、操作系統(tǒng)進(jìn)行交互,或者為了提高程序的性能。JNI標(biāo)準(zhǔn)至少保證本地代碼能工作在任何Java 虛擬機(jī)實(shí)現(xiàn)下。
??? JNI(Java Native Interface)的書寫步驟
public class StringDLL{
??? static
??? {
??? System.loadLibrary("testStringJNI");
??? }
??? public native static String get();
??? public native static void set(String name);
??? public static void main(String[] args){
??? ??? StringDLL s = new StringDLL();
??? ??? s.set("Hello world");
??? ??? System.out.println(s.get());
??? }
}
如果是靜態(tài)類型方法則生成的頭文件中方法的第二個(gè)參數(shù)是對(duì)java類的引用(JNIEnv *, jclass),如不是靜態(tài)類型則是對(duì)對(duì)象的引用(JNIEnv *, jobject)
使用javah 生成擴(kuò)展名為h的頭文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class StringDLL */
#ifndef _Included_StringDLL
#define _Included_StringDLL
#ifdef __cplusplus
extern "C" {
#endif
/*
?* Class:???? StringDLL
?* Method:??? get
?* Signature: ()Ljava/lang/String;
?*/
JNIEXPORT jstring JNICALL Java_StringDLL_get
? (JNIEnv *, jclass);
/*
?* Class:???? StringDLL
?* Method:??? set
?* Signature: (Ljava/lang/String;)V
?*/
JNIEXPORT void JNICALL Java_StringDLL_set
? (JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
使用C實(shí)現(xiàn)本地方法
#include "stdafx.h"
#include "testStringJNI.h"
#include <stdlib.h>
const char * chs;
jstring s;
JNIEXPORT jstring JNICALL Java_StringDLL_get(JNIEnv *env, jclass cls)
{??? ???
??? /* 簡(jiǎn)單返回轉(zhuǎn)換const char為jstring */
??? return (*env)->NewStringUTF(env,chs);
}
JNIEXPORT void JNICALL Java_StringDLL_set(JNIEnv *env, jclass cls, jstring s)
{
??? chs = (*env)->GetStringUTFChars(env,s,0); //java與C類型不同,需用JNI方法進(jìn)行轉(zhuǎn)換
}
注意,我們總是用接口指針 env 來操作 Java 對(duì)象。
使用C++實(shí)現(xiàn)本地方法
#include "stdafx.h"
#include "testStringJNI.h"
#include <stdlib.h>
const char * chs;
jstring s;
JNIEXPORT jstring JNICALL Java_StringDLL_get(JNIEnv *env, jclass cls)
{??? ???
??? /* 簡(jiǎn)單返回轉(zhuǎn)換const char為jstring */
??? return env->NewStringUTF(chs);
}
JNIEXPORT void JNICALL Java_StringDLL_set(JNIEnv *env, jclass cls, jstring s)
{
??? chs = env->GetStringUTFChars(s,0); //java與C類型不同,需用JNI方法進(jìn)行轉(zhuǎn)換
}
使用 C++ 后,源代碼變得更為直接,且接口指針參數(shù)消失。但是,C++ 的內(nèi)在
機(jī)制與 C 的完全一樣。在 C++ 中,JNI 函數(shù)被定義為內(nèi)聯(lián)成員函數(shù),它們將擴(kuò)
展為相應(yīng)的 C 對(duì)應(yīng)函數(shù)。
生成DLL文件
在.NET下新建Win32 Project工程名字為“testStringJNI”
在Application Setting里Aplication type點(diǎn)選DLL
拷貝頭文件到工程中
書寫C++程序?qū)崿F(xiàn)頭文件中定義的方法(見上頁)
按F7或Build -> Build? Solution
我們生成DLL文件就放在工程目錄下Debug文件夾里。名字就是 工程名.DLL
拷貝DLL到j(luò)ava文件目錄下,運(yùn)行java就可以看到控制臺(tái)打印出“One world”
一個(gè)簡(jiǎn)單java通過JNI調(diào)用C、C++就完成了
??? 使用java與本地已編譯的代碼交互,通常會(huì)喪失平臺(tái)可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的,比如,使用一些舊的庫,與硬件、操作系統(tǒng)進(jìn)行交互,或者為了提高程序的性能。JNI標(biāo)準(zhǔn)至少保證本地代碼能工作在任何Java 虛擬機(jī)實(shí)現(xiàn)下。
??? JNI(Java Native Interface)的書寫步驟
- 編寫帶有native聲明的方法的java類
- 使用javac命令編譯所編寫的java類
- 使用javah? jni java類名生成擴(kuò)展名為h的頭文件???
- 使用C/C++實(shí)現(xiàn)本地方法???
- 將C/C++編寫的文件生成動(dòng)態(tài)連接庫
public class StringDLL{
??? static
??? {
??? System.loadLibrary("testStringJNI");
??? }
??? public native static String get();
??? public native static void set(String name);
??? public static void main(String[] args){
??? ??? StringDLL s = new StringDLL();
??? ??? s.set("Hello world");
??? ??? System.out.println(s.get());
??? }
}
如果是靜態(tài)類型方法則生成的頭文件中方法的第二個(gè)參數(shù)是對(duì)java類的引用(JNIEnv *, jclass),如不是靜態(tài)類型則是對(duì)對(duì)象的引用(JNIEnv *, jobject)
使用javah 生成擴(kuò)展名為h的頭文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class StringDLL */
#ifndef _Included_StringDLL
#define _Included_StringDLL
#ifdef __cplusplus
extern "C" {
#endif
/*
?* Class:???? StringDLL
?* Method:??? get
?* Signature: ()Ljava/lang/String;
?*/
JNIEXPORT jstring JNICALL Java_StringDLL_get
? (JNIEnv *, jclass);
/*
?* Class:???? StringDLL
?* Method:??? set
?* Signature: (Ljava/lang/String;)V
?*/
JNIEXPORT void JNICALL Java_StringDLL_set
? (JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
使用C實(shí)現(xiàn)本地方法
#include "stdafx.h"
#include "testStringJNI.h"
#include <stdlib.h>
const char * chs;
jstring s;
JNIEXPORT jstring JNICALL Java_StringDLL_get(JNIEnv *env, jclass cls)
{??? ???
??? /* 簡(jiǎn)單返回轉(zhuǎn)換const char為jstring */
??? return (*env)->NewStringUTF(env,chs);
}
JNIEXPORT void JNICALL Java_StringDLL_set(JNIEnv *env, jclass cls, jstring s)
{
??? chs = (*env)->GetStringUTFChars(env,s,0); //java與C類型不同,需用JNI方法進(jìn)行轉(zhuǎn)換
}
注意,我們總是用接口指針 env 來操作 Java 對(duì)象。
使用C++實(shí)現(xiàn)本地方法
#include "stdafx.h"
#include "testStringJNI.h"
#include <stdlib.h>
const char * chs;
jstring s;
JNIEXPORT jstring JNICALL Java_StringDLL_get(JNIEnv *env, jclass cls)
{??? ???
??? /* 簡(jiǎn)單返回轉(zhuǎn)換const char為jstring */
??? return env->NewStringUTF(chs);
}
JNIEXPORT void JNICALL Java_StringDLL_set(JNIEnv *env, jclass cls, jstring s)
{
??? chs = env->GetStringUTFChars(s,0); //java與C類型不同,需用JNI方法進(jìn)行轉(zhuǎn)換
}
使用 C++ 后,源代碼變得更為直接,且接口指針參數(shù)消失。但是,C++ 的內(nèi)在
機(jī)制與 C 的完全一樣。在 C++ 中,JNI 函數(shù)被定義為內(nèi)聯(lián)成員函數(shù),它們將擴(kuò)
展為相應(yīng)的 C 對(duì)應(yīng)函數(shù)。
生成DLL文件
在.NET下新建Win32 Project工程名字為“testStringJNI”
在Application Setting里Aplication type點(diǎn)選DLL
拷貝頭文件到工程中
書寫C++程序?qū)崿F(xiàn)頭文件中定義的方法(見上頁)
按F7或Build -> Build? Solution
我們生成DLL文件就放在工程目錄下Debug文件夾里。名字就是 工程名.DLL
拷貝DLL到j(luò)ava文件目錄下,運(yùn)行java就可以看到控制臺(tái)打印出“One world”
一個(gè)簡(jiǎn)單java通過JNI調(diào)用C、C++就完成了
轉(zhuǎn)載于:https://blog.51cto.com/39387/78069
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的Java JNI浅析(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Internet Explorer7.0
- 下一篇: 微处理器又称为什么