1. Tnative.java
首先创建目录结构: com\test\,然后在test目录下创建一个java类Tnative.java 。
关键之处有2个地方
System.loadLibrary("hello");这句代码用于加载动态链接库(hello.dll)。
public static native void hello();声明一个native方法,该方法没有方法体,说明需要调用其他语言实现。
package com.test; public class Tnative { static { System.loadLibrary("hello"); } public static native void hello(); public static void main(String[] args) { hello(); } }
2. 编译java文件
首先设置环境变量:classpath=.;T:\work
javac Tnative.java 命令生成文件:Tnative.class
javah com.test.Tnative 命令生成文件:com_test_Tnative.h
3. 编写C代码com_test_Tnative.c,实现头文件com_test_Tnative.h里面的方法。
com_test_Tnative.h:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_test_Tnative */ #ifndef _Included_com_test_Tnative #define _Included_com_test_Tnative #ifdef __cplusplus extern "C" { #endif /* * Class: com_test_Tnative * Method: hello * Signature: ()V */ JNIEXPORT void JNICALL Java_com_test_Tnative_hello (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif
com_test_Tnative.c
#include <stdio.h> #include "com_test_Tnative.h" JNIEXPORT void JNICALL Java_com_test_Tnative_hello (JNIEnv * env, jclass obj) { printf("hello !"); }
3. 编译c文件,生成动态库hello.dll
首先介绍使用VC++2010编译器:
1. 新建 --> 输入名称:hello --> 选择DLL,空项目。
2. 把文件com_test_Tnative.h,com_test_Tnative.c复制到项目里。
3. 右击hello --> 属性 --> C++目录 --> 包含目录 --> 编辑
在这里添加2项头文件包含路径:
$(java_home)\include
$(java_home)\include\win32
4.然后开始编译,将生成的文件 hello.dll 放入环境变量classpath的路径下(classpath=.;T:\work);
5.然后运行:
java com.test.Tnative
6.也可以吧 hello.dll 放入其他目录,然后用-D指定动态库路径:
java com.test.Tnative -Djava.library.path=T:\work\vc\hello\Debug\
使用MinGW编译器:
1. 设置环境变量:c_include_path=%java_home%\include;%java_home%\include\win32;
2. 生成控制台模式的标准动态库,(不能用于jni)
gcc -o hello.dll -shared com_test_Tnative.c
3. 生成jni调用的动态库
gcc -o hello.dll -shared com_test_Tnative.c -Wl,--add-stdcall-alias
参数:-Wl,--add-stdcall-alias 可以为函数加上标准调用前缀(stdcall @nn)。
这样编译出的dll就可以了。都知道win32中dll中的函数要求有标准调用前缀,在JNI中不方便手动处理这个,Sun又没说清楚这事由编译器办。所以搞得我很郁闷。