Java学习笔记:JNI的使用(2016年1月13日14:21:45)
Jni(Java Native Interface)是java通过dll文件调用c/c++语言的方法。
以下为引用他人图片:
public static native void hello();
首先,在java里声明native类,类似与抽象类。
!注: 有static时候,在生成的.h头文件中是jclass,没有static时候是jobject 。
static
{
try
{
addDir("G:\\C\\dll\\TestHello\\x64\\Release");
}
catch (IOException e)
{
e.printStackTrace();
}
System.loadLibrary("JNI_TestHello");
}
随后,设置导入dll文件——System.loadLibrary(“JNI_TestHello”);
addDir(“G:\C\dll\TestHello\x64\Release”);是设置(自定义)java.library.path位置,链接dll文件
addDir源代码
public static void addDir(String s) throws IOException
{
try
{
Field field = ClassLoader.class.getDeclaredField("usr_paths");
field.setAccessible(true);
String[] paths = (String[]) field.get(null);
for (int i = 0; i < paths.length; i++)
{
if (s.equals(paths[i]))
{
return;
}
}
String[] tmp = new String[paths.length + 1];
System.arraycopy(paths, 0, tmp, 0, paths.length);
tmp[paths.length] = s;
field.set(null, tmp);
//
}
catch (IllegalAccessException e)
{
throw new IOException(
"Failed to get permissions to set library path");
}
catch (NoSuchFieldException e)
{
throw new IOException(
"Failed to get field handle to set library path");
}
}
}
运行程序,因为没有dll文件,所以无法运行。
找到程序所在的目录中的class文件。(TestHello.class)
在外面的bin目录下,打开cmd(Shift+右键,在命令行打开)。
输入
javah -jni JNI.TestHllo
JNI为包名,必须输入完整的包名
在bin下生成了JNI_TestHello.h文件。
打开Visual Studio,新建项目,win32控制台应用程序
如图:
如果你是64位的JDK,在选择x64调试器。
把刚刚生成的.h头文件复制到c工程目录下.h文件所在的目录。在studio中右键头文件添加现有项。
因为缺少jni.h系类的头文件,所以右键工程,属性,c/c++,附加包含目录,添加jdk下include目录和include里的win32目录。
在stdafx.h文件中,添加#include “jni.h” #include “JNI_TestHello.h”
在JNI_TestHello.cpp文件中写入程序。注意JNIEXPORT void JNICALL Java_JNI_TestHello_hello(JNIEnv *, jclass)是.h文件中自动生成的,复制过来即可。
点击生成,产生dll文件,复制到你指定的目录下。即可运行。
java与c的相互传值
JNIEXPORT jintArray JNICALL Java_com_jni_sort_Bubble_1sort_Bubble
(JNIEnv *env, jclass, jintArray a, jint size)
{
jint* array;//设定c中的数组
jintArray result;//设定返回值
result = env->NewIntArray(size);//设定返回值数组的大小
array = env->GetIntArrayElements(a, false);//将java的数组转换为c的数组
jint buff;
for (int i = 0; i < size-1; i++)
{
for (int j = i+1; j < size; j++)
{
if (array[i] > array[j])
{
buff = array[i];
array[i] = array[j];
array[j] = buff;
}
}
}
env->SetIntArrayRegion(result, 0, size, array);//将c的数组转换为java的数组
env->ReleaseIntArrayElements(a, array, 0);//释放还是什么的,不懂暂时
return result;
}