前几天学习时打开了jdk源码包,看了集合框架的一些源码,想着深化学习下,可是不知道怎么就打开了FileOpenInputStream的源码,看到了下面四个native方法(当然还有其它native方法):
private native void open0(String name) throws FileNotFoundException;
private native int readBytes(byte b[], int off, int len) throws IOException;
private native void close0() throws IOException;
于是有了一些联想。联系到c中的下列函数:
FILE *fopen( const char * filename, const char * mode );
char *fgets( char *buf, int n, FILE *fp );
int fclose( FILE *fp );
可不是嘛,真像(真香警告!!哈哈),写到这里想着要不就把这三个本地方法给实现编写个自己的FileInputStream,猜测也许可能分别调用这三个方法可能行不通呢,但学习可不就是这样,不去试着搞搞,怎么提升自己,嘿嘿。希望以后自己看到自己现在的学习状态不会嘲笑自己吧。
在实现这条路上需要补全很多这方面的知识,JNI的API的熟悉,JNI数据类型与C++中数据类型转换...
大前天和昨天都在实现native方法调用。中间一天佩女朋友了哈哈。在实现过程中当然中间遇到一些问题啦。遇到问题是好事,在解决问题中你可以获得很多没有遇到问题时的知识。
*JNI(java native interface) ,它提供了若干的
API实现了Java和其他语言的通信(主要是
C&
C++)
JNI使用的副作用:
1、程序不再
跨平台。要想跨平台,必须在不同的系统环境下重新编译本地语言部分。
2、程序不再是绝对安全的,本地代码的不当使用可能导致整个程序崩溃。
这里记录下实现一个简单的JNI列子:
1.编写好例子HelloWorld.java
public class HelloWorld{
public native void sayHello();
static{
System.loadLibrary("hello"); //引用动态链接库的名称
}
public static void main(String[] args){
new HelloWorld().sayHello();
}
}
*System.loadLibrary("hello");在这里声明JNI的不再跨平台,不同系统平台下加载引用的动态链接库不同
windows平台下调用的动态链接库为hello.dll
linux平台下调用动态链接库为hello.so
2.在编译生成动态链接库前,先编写本地实现代码c/c++
1)在编写c/c++代码前,在当前环境下编译HelloWorld.java程序,使用使用工具javah将使用生成程序要使用的头文件HelloWorld.h,执行命令( javah -jni HelloWorld),不同系统平台下头文件都一样。
2)引用上面头文件编写实现代码HelloWorld.c
#include
#include "HelloWorld.h"
JNIEXPORT void JNICALL Java_HelloWorld_sayHello(JNIEnv *jbi, jobject obj){
printf("HelloWorld");
return;
}
3.生成动态链接库
windows下可使用vc++(推荐),mingw或其他
mingw官方解释编译
http://www.mingw.org/node/41
windows操作系统java HelloWorld运行生成的dll动态链接库调用时错误:
Can't load IA 32-bit .dll on a AMD 64-bit platform with 32 bit JVM
错误信息为64位的VM不能加载32位的dll(通过java -version查看本机安装VM为多少位的)
默认mingw编译32位操作系统程序。
可下载mingw-w64配置后编译为64位系统程序(hello.dll),
自己在编译时系统内部报错跳过该方法,使用了vc++生成64位的hello.dll,毕竟微软家的系统和微软家的vc++;
总结:不同位数的操作系统,运行着不同位数的VM,而VM只支持相同位数的程序时。不同平台的复杂性,造就了跨平台的重要性。
linux中使用系统自带gcc编译生成
-I大写的i
gcc -I$JAVA_HOME/java/include -I$JAVA_HOME/java/include/linux HelloWorld.c -fPIC -shared -o hello.so
4.最后执行 java HelloWorld 得到输出内容
。。。。。。。。。。后续实现文章开头想要尝试的,不是一时半伙完成的,坚持住。