大二java和数据结构都需要课程设计,想偷懒所以做了一个排序可视化的程序,java和C语言混合编程,两科都只用这一个课程设计就行了,嘿嘿
首先java要确定好那些类的那些方法是要用C语言写的,加上native
class NativeSort
{
//冒泡排序
public native int[][] BubbleSort(int[] unsortedArray,int v);
//快速排序
public native int[][] QuickSort(int[] unsortedArray,int v);
//插入排序
public native int[][] InsertionSort(int[] unsortedArray,int v);
//选择排序
public native int[][] SelectionSort(int[] unsortedArray,int v);
//希尔排序
public native int[][] ShellSort(int[] unsortedArray,int v);
public native int[][] MergeSort(int[] unsortedArray,int v);
}
然后控制台javac进行编译,找到这个NativeSort.class文件,然后javah 这个文件编译出头文件,注意这个.class文件一定要加包名,否则找不到
得到头文件后,就拿这个头文件去vs里面建个dll工程,注意配置管理器改成64位,现在没有人用32位的jdk了吧
jni.h和jni_md去你安装java的地方找就行,这两个是必须的,因为一会你的函数主体里面语法和数据结构类型和正常写C语言不太一样,都需要依赖这两个头文件,数据结构类型不一样也是混合编程里面最麻烦的地方
新建一个nativeSort.c然后里面函数名,直接去javah编译出来的头文件找就行了,函数名由头文件确定了,无法再更改
JNIEXPORT jobjectArray JNICALL Java_c_1dll_1sort_NativeSort_BubbleSort
(JNIEnv *env, jobject object, jintArray unsortedArray, jint v)
JNIEnv *env, jobject object都是必须的参数,env用来后面的参数类型转化
jintArray unsortedArray, jint v就是我自定义的一个整形数组和整形参数
具体代码如下
jobjectArray result;
jclass intArrCls = env->FindClass("[I");//JNI通过它来确定引用的类型的,I代表整数,[代表数组
result = env->NewObjectArray(10000, intArrCls, NULL);
jint *carr;//将jintArray转化成能使用的int[]类型
carr = env->GetIntArrayElements(unsortedArray, false);
jint temp = 0;
jint isSorted;
jint a=0;//循环二维数组
for (int i = 0; i <100; i++) {
isSorted = 1; //假设剩下的元素已经排序好了
for (int j = 0; j < 100 - i; j++) {
if (v == 0)//升序
{
if (carr[j] < carr[j + 1]) {
temp = carr[j];
carr[j] = carr[j + 1];
carr[j + 1] = temp;
isSorted = 0; //一旦需要交换数组元素,就说明剩下的元素没有排序好
jintArray iarr = env->NewIntArray(100);//为一维int数组iarr分配空间
env->SetIntArrayRegion(iarr, 0, 100, carr);//为iarr赋值
env->SetObjectArrayElement(result, a, iarr);
env->DeleteLocalRef(iarr);
a++;
}
}
else {//降序
if (carr[j] > carr[j + 1]) {
temp = carr[j];
carr[j] = carr[j + 1];
carr[j + 1] = temp;
isSorted = 0; //一旦需要交换数组元素,就说明剩下的元素没有排序好
jintArray iarr = env->NewIntArray(100);//为一维int数组iarr分配空间
env->SetIntArrayRegion(iarr, 0, 100, carr);//为iarr赋值
env->SetObjectArrayElement(result, a, iarr);
env->DeleteLocalRef(iarr);
a++;
}
}
}
if (isSorted) break; //如果没有发生交换,说明剩下的元素已经排序好了
}
return result;
}
以上结合注释大概能看明白,可以发现一些数据类型的创建赋值都需要使用jdk头文件特定的语法
这样生成一下去x64文件夹找一下dll文件放到你java项目的bin文件下,别的地方下也可以,修改一下路径就行了
java调用代码如下
try {
System.loadLibrary("NativeSort");//加载由C编译器生成的DLL文件。
NativeSort nSort= new NativeSort();
int[][] a=nSort.InsertionSort(unsortedArray, v);
return a;
}
catch (Exception e) {
// TODO: handle exception
System.out.print(e);
}
调用不成功看看dll文件路径设置了吗
这样一个流程就下来了,主要的问题可能就各个数据类型变化太大资料较少不太好编
诸君共勉!