您的位置:首页 > 编程语言 > C语言/C++

JNI实现java调用C语言实现底层代码

2014-05-29 17:50 531 查看

JNI实现java调用C语言实现底层代码

在java中,很多sun公司定义的java代码中, 都有native方法, 它没有方法体,只有参数和返回值。这个方法究竟是什么呢?它其还是一个java和C/C++的一个接口方法。通过native方法, java可是实现调用C/C++的函数。
多数人是通过JNI和NIO的方法实现。当前我学习的是JNI
JNI: java native interface (java本地接口调用)。java代码中,使用native方法,我们就以所有学习程序设计语言第一个程序HelloWorld来做介绍。
具体实现:
1)java部分代码:
public class HelloWorld{
	static{
		System.loadLibrary("src/test1");
	}
	public native void display();
	public static void main(String[] args){
		new HelloWorld().display();
	}
}
jvm机制简单介绍一下,jvm采用懒加载机制,在调用一个类的时候,采取加载。在HelloWorld类中, static静态块加载进内存中, System.loadLibrary("src/test1");会自动调用src/test1这个文件,该文件就是C/C++生成的.dll依赖文件。这里是test1.dll。当加载的时候,就会调用.dll文件,调用C代码。
那么我们先将Helloworld.java 通过javac编译,然后使用javah命令,会生成HelloWorld.h头文件,用于C/C++中加入到代码中。使用 :javah HelloWorld
打开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: display

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_HelloWorld_display

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

这里的NIEXPORT void JNICALL Java_HelloWorld_display (JNIEnv *, jobject);就是生成的C类型的java方法。
2)编写C/C++,,使用visual stuio 2010
新建cpp文件,文件名和java中System.loadLibrary("src/test1");这个test1文件名相同, 因为到时候生成的dll文件时以CPP文件名命名。
新建步骤:win32项目--->dll(这里输出符号打钩)
我们将JNIEXPORT void JNICALL Java_HelloWorld_display(JNIEnv *, jobject); 这段头文件中的代码拷贝到cpp文件中,然后为这个函数体编写函数体。函数体中,我们直接输出一句话cout<<"HelloWorld";用于在java控制台显示,说明就调用了C的代码。
函数是写了,但是函数从哪儿来??当然是HelloWorld.h中声明咯,就在cpp文件中引入该头文件。而JNIEnv *,等这些类型,都是哪里定义的呢?看Helloworld.h头文件,,它引入了个jni.h头文件,这个头文件其实在JDK安装目录下%J***A_HOME%\include
而jni.h又引用了jni_md.h 这个在%J***A_HOME%\include\win32目录下,然后把这2个头文件拷贝到C工程下。
运行,生成dll,将它拷贝到java目录中, 但是运行的时候发现报异常,java.lang.UnsatisfiedLinkError:
Couldn ‘t load testcpp: findLibrary returned 。。Can't load IA 32-bit .dll on a AMD 64-bit platform,,是dll的格式为32位的,而平台式64位的, 百度,,然后知道了,将运行那里本身是win32,改成x64就OK。编译,重新拷贝一次dll,运行,就可以输出Hellowolrd这个字符串,,是不是很神奇?


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: