java JNI编程简单实践

JNI简介

在维基百科中对JNI的定义如下:JNI (Java Native Interface,Java本地接口)是一种编程框架,使得Java虚拟机中的Java程序可以调用本地应用/或库,也可以被其他程序调用。 本地程序一般是用其它语言(C、C++或汇编语言等)编写的,并且被编译为基于本机硬件和操作系统的程序。在Java语言中native方法就是使用JNI技术来实现的,通过JNI技术可以调用底层C++或C语言编写的代码。

简单示例

HelloWorld

public class HelloWorld {
	public native void displayHelloWorld();
	private int a = 0;

	static {
		System.loadLibrary("HelloWorldImpl");
	}

	public static void main(String[] args) {
		HelloWorld helloWorld = new HelloWorld();
		System.out.println("a1\t"+helloWorld.a);
		helloWorld.displayHelloWorld();
		System.out.println("a2\t"+helloWorld.a);
	}
}

首先定义一个HelloWorld类,其中有一个private变量a和一个native方法displayHelloWorld,通过javac对java文件进行编译生成.class文件,随后使用javah -jni HelloWorld 指令生成一个HelloWorld.h文件。
HelloWorld.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    displayHelloWorld
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

生成HelloWorld.h文件后需要将JAVA_HOME\inclide下的jni.h文件导入到HelloWorld.h文件同一文件夹中,然后再将JAVA_HOME\inclide\win32下的jni_md.h文件也导入到HelloWorld.h同一文件夹中,这样才能进行编译。其中JNIEXPORT 的原型的JNICALL说明函数的参数由右向左入栈,JNIEXPORT表示外部可以调用该函数。
然后编写一个新的文件HelloWorld.cpp,同时导入HelloWorld.h。
HelloWorld.cpp

#include "HelloWorld.h"
#include <stdio.h>

int temp = 0;

JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
  (JNIEnv * env, jobject thiz) {
	printf("Hello world!");
	return;
}

然后使用gcc编译器或者vs自动的编译器对HelloWorld文件进行编译生成HelloWorldImpl.dll文件。

gcc -Wall -shared HelloWorld.cpp -o HelloWorldImpl.dll

运行java HelloWorld就可以看到频幕上打印出了Hello World

变量获取和赋值

HelloWorld.java和上文一样,改变HelloWorld.cpp文件

HelloWorld.cpp:

#include "HelloWorld.h"
#include <stdio.h>

int temp = 0;

JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
  (JNIEnv * env, jobject thiz) {
	jfieldID id;
	jclass c;
	c = env->FindClass("HelloWorld");
	if (c==NULL)
	{
		printf("FindClass failed");
		return;
	}
	id = env -> GetFieldID( c, "a", "I");
	if (id==NULL)
	{
		printf("GetFiledID failed");
		return;
	}
	env->SetIntField(thiz, id, 20);
	return;
}

在新的cpp文件中定义了一个jfield和jclass,通过FindClass文件找到HelloWorld的class,然后使用GetDieldID获取a属性的id,然后再该object中找到a的位置,然后对a的值进行修改,调用SetIntField函数,可以对当前对象下的a属性进行修改,将a的值修改为20。

运行java HelloWorld可以看到第一个a为0第二个a为20。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值