java调用C语言编程技术详解

大二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文件路径设置了吗

这样一个流程就下来了,主要的问题可能就各个数据类型变化太大资料较少不太好编

诸君共勉!

发布了43 篇原创文章 · 获赞 8 · 访问量 3917

猜你喜欢

转载自blog.csdn.net/MaYang_/article/details/103729744