大王交代的任务,做一个leetcode给本科生的计算系统基础用。大王是我的老板。
众所周知,大家熟悉的LEETCODE是一个很大的项目,我需要做它的一个子集——只需要测试C语言的函数即可。别的语言管不着(但是需要预留扩展空间。万一证涛或喉结看上我这系统,让我加个判C++题的功能呢哈哈哈哈哈哈哈【醒醒】)。另外,LEETCODE上面全是算法大题,我的leetcode上面应该只有难度相当于“实现一个函数int add(int x, int y),返回值是两个输入参数的和”这种小题。学院200+人,可能平时0访问,考试时瞬间并发很高,不过这是另一个问题。
2012年我是软院的大一新生,我经历的是gcc+命令行时代。
五年后的现在,大一同学使用的是vs2013+我的研究生同学开发的vs插件。大王对此非常不满,因为微软无视c11,私自更改一些库函数,像scanf_s,printf_s等,所以把这项目抛出来让今年的研究生干活。我脑袋一热就接了。
那么问题来了,俗话说得好,接活容易干活难,俗话又说得好,践约如偿债。整整一个半学期以来,我这个大学渣每天挣扎在及格线上,根本没时间管这个项目,每周例会无法正面大王因为每周都是无限划水,划水到什么程度呢,划水次数多到大王关心地打算派另外两个同学来跟我一起干。我看起来像那么容易屈服的人吗?<del>当然是。</del>当然还要垂死挣扎一下。我说,老师我打算在寒假里干这个来着,这一个半学期以来我的课表都很满所以平时进度很差,寒假里我一定好好做事。大王信了。
时间如白驹过隙。寒假到了。然而事实上我的脸好像被自己打肿了……
自从放寒假以来每天吃喝玩乐,懒散到自己都看不下去了。
今天开个头。以后每天至少一更好吧。
-------------------------------------2018.2.3----------------------------------------------
windows。java1.8,gcc已添加到path。IDE是Eclipse。
C部分,workspace是D:\gcc-workspace,里面放头文件和c源代码。(这里的结构将来需要细改,因为学生有两百多个,两百多个.c文件放在这里很难看)
Java部分,workspace是D:\eclipse-j2ee-workspace。项目名为D:\eclipse-j2ee-workspace\JNITest。项目结构如下:
Sample1.java内容如下:
package cn.edu.nju.zyf.demo;
public class Sample1 {
public native int intMethod(int n);
public native boolean booleanMethod(boolean bool);
public native String stringMethod(String text);
public native int intArrayMethod(int[] intArray);
}
Test.java内容如下:
package cn.edu.nju.zyf.demo;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.loadLibrary("Sample333");
Sample1 sample = new Sample1();
int square = sample.intMethod(5);
boolean opposite = sample.booleanMethod(true);
String text = sample.stringMethod("Java");
int sum = sample.intArrayMethod(new int[] {1,2,3,4,5,6,7,8,9,10});
System.out.println("intMethod: " + square);
System.out.println("booleanMethod: " + opposite);
System.out.println("stringMethod: " + text);
System.out.println("intArrayMethod: " + sum);
}
}
关于上面的System.loadLibrary("Sample333");的参数,它是Sample333.dll文件的文件名。
编完Sample1.java,手动打开cmd,使用javah命令生成头文件。以后可以改成Runtime.exec什么什么的:
C:\Users\yuanf>javah -classpath D:\eclipse-j2ee-workspace\JNITest\bin -d d:\gcc-workspace -jni cn.edu.nju.zyf.demo.Sample1
在D:\gcc-workspace生成cn_edu_nju_zyf_demo_Sample1.h如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class cn_edu_nju_zyf_demo_Sample1 */
#ifndef _Included_cn_edu_nju_zyf_demo_Sample1
#define _Included_cn_edu_nju_zyf_demo_Sample1
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: cn_edu_nju_zyf_demo_Sample1
* Method: intMethod
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_cn_edu_nju_zyf_demo_Sample1_intMethod
(JNIEnv *, jobject, jint);
/*
* Class: cn_edu_nju_zyf_demo_Sample1
* Method: booleanMethod
* Signature: (Z)Z
*/
JNIEXPORT jboolean JNICALL Java_cn_edu_nju_zyf_demo_Sample1_booleanMethod
(JNIEnv *, jobject, jboolean);
/*
* Class: cn_edu_nju_zyf_demo_Sample1
* Method: stringMethod
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_cn_edu_nju_zyf_demo_Sample1_stringMethod
(JNIEnv *, jobject, jstring);
/*
* Class: cn_edu_nju_zyf_demo_Sample1
* Method: intArrayMethod
* Signature: ([I)I
*/
JNIEXPORT jint JNICALL Java_cn_edu_nju_zyf_demo_Sample1_intArrayMethod
(JNIEnv *, jobject, jintArray);
#ifdef __cplusplus
}
#endif
#endif
想到这突然感觉用jni做leetcode是个无底洞。
既然java提供了操作cmd的方法,我还不如把学生传上来的C函数复制粘贴到一个C文件的main函数里然后调用那个main函数呢。
但是又舍不得jni这个高逼格的东西,我能预计从jni学会很多东西带来的快感。
联想到哨冻的课,联想到人件的章节,设计才是软件开发的第一难题啊。