前言:
在查看java socket实现代码时最终发现其是通过JNI去调用系统级的soket接口实现soket连接的,因此对JNI做了一点学习。
JNI 就是java本地接口 ,是通过java调用本地系库实现指定功能的方法,下面通过一个最简单的例子做一下记录。
1. 创建java 类:
class HelloWorld{
private native void print();
public static void main (String[] args){
new HelloWorld().print();
}
static{
System.loadLibrary("HelloWorld");
}
}
2. 编译java 文件
javac HelloWold.java
3. 生成 .h文件
javah -jni HelloWorld
4. 创建 C 文件
#include <jni.h> #include <stdio.h> #include "HelloWorld.h" JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj) { printf("java invoke c dll ,it's very cool!\n"); return; }
5 . 生成 dll文件
set include=D:\Program Files\Microsoft Visual Studio 9.0\VC\include
set lib=D:\Program Files\Microsoft Visual Studio 9.0\VC\lib
cl -Ic:\java\include -Ic:\java\include\win32 -MD -LD HelloWorld.c -FeHelloWorld.dll
mt.exe -manifest HelloWorld.dll.manifest -outputresource:HelloWorld.dll;2
6. 执行程序
java HelloWorld
7. 结果
java invoke c dll ,it's very cool!
8. 为了更方便的操作对以上步骤做了一个批处理文件
@echo off
echo ----------start compile java file----------
javac HelloWorld.java
echo ----------start generate .h file----------
javah -jni HelloWorld
echo Please create the c file, Press enter to continue when you complete it .
pause
echo ----------start generate .dll file----------
set include=D:\Program Files\Microsoft Visual Studio 9.0\VC\include
set lib=D:\Program Files\Microsoft Visual Studio 9.0\VC\lib
cl -Ic:\java\include -Ic:\java\include\win32 -MD -LD HelloWorld.c -FeHelloWorld.dll
mt.exe -manifest HelloWorld.dll.manifest -outputresource:HelloWorld.dll;2
echo ----------end generate dll file----------
echo ----------start execute javaApp ----------
java HelloWorld
echo ----------end execute javaApp ----------
pause
后记:
在实际的执行过程中遇到了很多奇怪的问题下面总结如下以便以后使用:
1. 找不到类
C:\Documents and Settings\Administrator\Desktop\学习\技术探路学习\JNI\demo>javah
-jni HelloWorld
Error: Could not find class file for 'HelloWorld'.
解决方法:
javah -jni -classpath . com.example.hellojni.HelloJni
2. 路径格式不对
david@xmomx:src$ javah -jni com/example/hellojni/HelloJni
javadoc: error - Illegal package name: "com/example/hellojni/HelloJni"
1 error
解决方法:
david@xmomx:src$ javah -jni com.example.hellojni.HelloJni
3. 找不到引入的h文件
cl -Ic:\java\include -IC:\Dev-Cpp\include -Ic:\java\include\win32 -MD -LD HelloWorld.cpp -FeHelloWorld.dll
4. 引入java 的库 -I
gcc HelloWorld.c -fPIC -shared -o HelloWorld.so -IC:\java\include -IC:\java\include\win32
5. windows 下编译dll文件
set include=D:\Program Files\Microsoft Visual Studio 9.0\VC\include
set lib=D:\Program Files\Microsoft Visual Studio 9.0\VC\lib
cl -Ic:\java\include -Ic:\java\include\win32 -MD -LD HelloWorld.c -FeHelloWorld.dll
5.1 LINK : fatal error LNK1104: 无法打开文件“kernel32.lib”
拷贝 kernel32.lib 到 D:\Program Files\Microsoft Visual Studio 9.0\VC\lib 目录下
5.2 JNI调用出现Runtime Error! R6034(引自:http://blog.sina.com.cn/s/blog_70584b480100lj5i.html)
mt.exe -manifest HelloWorld.dll.manifest -outputresource:HelloWorld.dll;2