探索JAVA知识的路上遇上了JNI

2019-04-13 16:26发布

前几天学习时打开了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 得到输出内容   。。。。。。。。。。后续实现文章开头想要尝试的,不是一时半伙完成的,坚持住。