用java的jni调用C语言的API,实现带图形界面的一元稀疏多项式计算器
来源:互联网 发布:爱家呐软件多少钱 编辑:程序博客网 时间:2024/06/06 10:02
实现步骤:
1) 完成Java代码,编写好Java调用类。
2) 编译你的Java类。
3) 用javah生成编译好的class文件对应的C/C++ 函数的头文件。
4) 实现头文件中的函数原型,编写native代码。
5) 将native代码编译打包成DLL库(win32)或共享库(Linux)。
6) 将你的Java代码跑起来
一、首先在创建一个类InvokerHelper。
1. 编写Java代码。
注意:
(1) 调用本地代码的java方法,要设置成native的。
(2) 要使用System的LoadLibrary方法去加载包含本地方法实现的库。
/src/helper/InvokerHelper.java
package helper;public class InvokerHelper {static {System.loadLibrary("PolynomialCaculator");}// 多项式相加public static native String AddPolyn(int n1, float[] coef1, int[] expn1, int n2, float[] coef2, int[] expn2);// 多项式相加public static native String SubtractPolyn(int n1, float[] coef1, int[] expn1, int n2, float[] coef2, int[] expn2);// 多项式相加public static native String MultiplyPolyn(int n1, float[] coef1, int[] expn1, int n2, float[] coef2, int[] expn2);}2、编译生成InvokerHelper.class
3、在cmd命令行中切换至eclipse的对应的workspace的bin目录下,执行命令javah -classpath . -jni helper.InvokerHelper。此处的helper为包 名,InvokerHelper为类名。此时生成一个helper_InvokerHelper.h文件。内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class helper_InvokerHelper */#ifndef _Included_helper_InvokerHelper#define _Included_helper_InvokerHelper#ifdef __cplusplusextern "C" {#endif/* * Class: helper_InvokerHelper * Method: AddPolyn * Signature: (I[F[II[F[I)Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_helper_InvokerHelper_AddPolyn (JNIEnv *, jclass, jint, jfloatArray, jintArray, jint, jfloatArray, jintArray);/* * Class: helper_InvokerHelper * Method: SubtractPolyn * Signature: (I[F[II[F[I)Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_helper_InvokerHelper_SubtractPolyn (JNIEnv *, jclass, jint, jfloatArray, jintArray, jint, jfloatArray, jintArray);/* * Class: helper_InvokerHelper * Method: MultiplyPolyn * Signature: (I[F[II[F[I)Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_helper_InvokerHelper_MultiplyPolyn (JNIEnv *, jclass, jint, jfloatArray, jintArray, jint, jfloatArray, jintArray);#ifdef __cplusplus}#endif#endif
4) 实现头文件中的函数原型,编写native代码。
创建一个DLL项目,这里我用devc++创建。文件->新建->项目->选择DLL工程。
以下有几个特别值得注意的地方:
1、要将生成的helper_InvokerHelper.h文件放到DLL工程的根目录,并将文件开头的#include <jni.h>改成#include "jni.h"
2、找到jdk的安装目录的jni.h与jni_md.h文件,将这两个文件复制到DLL工程的根目录。默认安装的话,这两个文件的路径为C:\Program Files\Java\jdk1.8.0_40\include和C:\Program Files\Java\jdk1.8.0_40\include\win32
接下来实现创建新的.c或.cpp文件(分别为C文件和C++文件),实现helper_InvokerHelper.h头文件中的方法,文件名应该与之前java的helper_InvokerHelper类中的System.loadLibrary()的名称相同。此处为我用C++语言,所以为PolynomialCaculator.cpp。将helper_InvokerHelper.h头文件中的方法复制粘贴到PolynomialCaculator.cpp,将方法逐一实现。
代码如下:
#include<stdio.h>#include "helper_InvokerHelper.h"#include "jni.h"#include<math.h>#include<stdlib.h> #include<string.h>typedef struct Polynomial{ float coef; //系数 int expn; //指数 struct Polynomial *next;}*Polyn,Polynomial;void Insert(Polyn p,Polyn h){ if(p->coef==0) free(p); //系数为0的话释放结点 else{ Polyn q1,q2; q1=h;q2=h->next; while(q2&& p->expn < q2->expn){ //查找插入位置 q1=q2; q2=q2->next;} if(q2&& p->expn == q2->expn){ //将指数相同相合并 q2->coef += p->coef; free(p); if(!q2->coef){ //系数为0的话释放结点 q1->next=q2->next; free(q2);}} else{ //指数为新时将结点插入 p->next=q2; q1->next=p;}}}Polyn CreatePolyn(int n, float coef[], int expn[]){ //建立一个头指针为head、项数为m的一元多项式 int i; Polyn p,head; p=head=(Polyn)malloc(sizeof(struct Polynomial)); head->next=NULL; for(i=0;i<n;i++){ p=(Polyn)malloc(sizeof(struct Polynomial)); //建立新结点以接收数据 p->coef=coef[i]; p->expn=expn[i]; Insert(p,head); //调用Insert函数插入结点} return head;}int compare(Polyn a,Polyn b){//比较多项式的指数的大小 if(a&&b){ if(!b||a->expn>b->expn) return 1; else if(!a||a->expn<b->expn) return -1; else return 0;} else if(!a&&b) return -1; //a多项式已空,但b多项式非空 else return 1; //b多项式已空,但a多项式非空}jstring PrintPolyn(Polyn P,JNIEnv * env){char buf[50];int a;int i=0;//指向下一个插入地址 int k=0;Polyn q=P->next; int flag=1; //项数计数器 if(!q){ //若多项式为空,输出0 buf[i]=0; i++; buf[i]=230; i++; char* tmpstr=buf; jstring rtstr = env->NewStringUTF(tmpstr); return rtstr;} while(q){//分离整数部分与小数部分int xiaoshu=((int)fabs(q->coef*10))%10; //第一位小数 if(q->coef>0&& flag!=1){ buf[i]='+'; //系数大于0且不是第一项 i++; printf("+");} if(q->coef!=1&&q->coef!=-1){ //系数非1或-1的普通情况 if(q->coef<0) { //添加负号 buf[i]='-'; i++; printf("-");}//添加整数部分 buf[i]=(int)(fabs(q->coef)); i++; printf("%d",(int)(fabs(q->coef))); if(xiaoshu!=0) { //添加小数点buf[i]='.'; i++; printf("."); //添加小数部分 buf[i]=xiaoshu; i++; printf("%d",xiaoshu);} if(q->expn==1){ buf[i]='X'; i++; printf("X"); } else if(q->expn){buf[i]='X';i++;printf("X");buf[i]='^';i++;printf("^");//添加指数的各位数 buf[i]=q->expn; i++; printf("%d",q->expn); } } else{ if(q->coef==1){ if(!q->expn){buf[i]=1;i++;printf("1"); } else if(q->expn==1){buf[i]='X';i++;printf("X");} else{buf[i]='X';i++;printf("X");buf[i]='^';i++;printf("^");//添加指数的各位数 buf[i]=q->expn; i++; printf("%d",q->expn); }} else if(q->coef==-1){ if(!q->expn){buf[i]='-';i++;printf("-");buf[i]=1;i++;printf("1"); } else if(q->expn==1){buf[i]='-';i++;printf("-");buf[i]='X';i++;printf("X"); } else{buf[i]='-';i++;printf("-");buf[i]='X';i++;printf("X");buf[i]='^';i++;printf("^");//添加指数的各位数 buf[i]=q->expn; i++; printf("%d",q->expn); } }} q=q->next; flag++;}buf[i]='\0'; char shu[strlen(buf)]; strcpy(shu,buf);char* tmpstr=shu; jstring rtstr = env->NewStringUTF(tmpstr); return rtstr;}Polyn AddPolyn(Polyn pa,Polyn pb){ //求解并建立多项式a+b,返回其头指针 Polyn qa=pa->next; Polyn qb=pb->next; Polyn headc,hc,qc; hc=(Polyn)malloc(sizeof(struct Polynomial)); //建立头结点 hc->next=NULL; headc=hc; while(qa||qb){ qc=(Polyn)malloc(sizeof(struct Polynomial)); switch(compare(qa,qb)){ case 1:{ qc->coef=qa->coef; qc->expn=qa->expn; qa=qa->next; break;} case 0:{ qc->coef=qa->coef+qb->coef; qc->expn=qa->expn; qa=qa->next; qb=qb->next; break;} case -1:{ qc->coef=qb->coef; qc->expn=qb->expn; qb=qb->next; break;} } if(qc->coef!=0){ qc->next=hc->next; hc->next=qc; hc=qc;} else free(qc); //当相加系数为0时,释放该结点} return headc;}JNIEXPORT jstring JNICALL Java_helper_InvokerHelper_AddPolyn (JNIEnv * env, jclass method, jint n1, jfloatArray coef1, jintArray expn1, jint n2, jfloatArray coef2, jintArray expn2){ jfloat* c1 = (env)->GetFloatArrayElements(coef1,0); jint* e1 = (env)->GetIntArrayElements(expn1, 0 ); float c11[n1]; int e11[n1]; int i; for(i=0;i<n1;i++) { c11[i]=c1[i]; e11[i]=e1[i]; } (env)->ReleaseFloatArrayElements(coef1, c1, 0 ); (env)->ReleaseIntArrayElements(expn1, e1, 0 ); jfloat* c2 = (env)->GetFloatArrayElements(coef2, 0 ); jint* e2 = (env)->GetIntArrayElements(expn2, 0 ); float c22[n2]; int e22[n2]; for(i=0;i<n2;i++) { c22[i]=c2[i]; e22[i]=e2[i]; } env->ReleaseFloatArrayElements(coef2, c2, 0 ); env->ReleaseIntArrayElements(expn2, e2, 0 ); Polyn pa=CreatePolyn(n1,c11,e11); Polyn pb=CreatePolyn(n2,c22,e22); Polyn qa=pa->next; Polyn qb=pb->next; Polyn headc,hc,qc; hc=(Polyn)malloc(sizeof(struct Polynomial)); //建立头结点 hc->next=NULL; headc=hc; while(qa||qb){ qc=(Polyn)malloc(sizeof(struct Polynomial)); switch(compare(qa,qb)){ case 1:{ qc->coef=qa->coef; qc->expn=qa->expn; qa=qa->next; break;} case 0:{ qc->coef=qa->coef+qb->coef; qc->expn=qa->expn; qa=qa->next; qb=qb->next; break;} case -1:{ qc->coef=qb->coef; qc->expn=qb->expn; qb=qb->next; break;} } if(qc->coef!=0){ qc->next=hc->next; hc->next=qc; hc=qc;} else free(qc); //当相加系数为0时,释放该结点}//测试代码 return PrintPolyn(headc,env); } JNIEXPORT jstring JNICALL Java_helper_InvokerHelper_SubtractPolyn (JNIEnv * env, jclass method, jint n1, jfloatArray coef1, jintArray expn1, jint n2, jfloatArray coef2, jintArray expn2) { jfloat* c1 = (env)->GetFloatArrayElements(coef1,0); jint* e1 = (env)->GetIntArrayElements(expn1, 0 ); float c11[n1]; int e11[n1]; int i; for(i=0;i<n1;i++) { c11[i]=c1[i]; e11[i]=e1[i]; } (env)->ReleaseFloatArrayElements(coef1, c1, 0 ); (env)->ReleaseIntArrayElements(expn1, e1, 0 ); jfloat* c2 = (env)->GetFloatArrayElements(coef2, 0 ); jint* e2 = (env)->GetIntArrayElements(expn2, 0 ); float c22[n2]; int e22[n2]; for(i=0;i<n2;i++) { c22[i]=c2[i]; e22[i]=e2[i]; } env->ReleaseFloatArrayElements(coef2, c2, 0 ); env->ReleaseIntArrayElements(expn2, e2, 0 ); Polyn pa=CreatePolyn(n1,c11,e11); Polyn pb=CreatePolyn(n2,c22,e22); Polyn h=pb; Polyn p=pb->next; Polyn pd; while(p){ //将pb的系数取反 p->coef*=-1; p=p->next;} pd=AddPolyn(pa,h); for(p=h->next;p;p=p->next) //恢复pb的系数 p->coef*=-1; return PrintPolyn(pd,env); } JNIEXPORT jstring JNICALL Java_helper_InvokerHelper_MultiplyPolyn (JNIEnv * env, jclass method, jint n1, jfloatArray coef1, jintArray expn1, jint n2, jfloatArray coef2, jintArray expn2) { jfloat* c1 = (env)->GetFloatArrayElements(coef1,0); jint* e1 = (env)->GetIntArrayElements(expn1, 0 ); float c11[n1]; int e11[n1]; int i; for(i=0;i<n1;i++) { c11[i]=c1[i]; e11[i]=e1[i]; } (env)->ReleaseFloatArrayElements(coef1, c1, 0 ); (env)->ReleaseIntArrayElements(expn1, e1, 0 ); jfloat* c2 = (env)->GetFloatArrayElements(coef2, 0 ); jint* e2 = (env)->GetIntArrayElements(expn2, 0 ); float c22[n2]; int e22[n2]; for(i=0;i<n2;i++) { c22[i]=c2[i]; e22[i]=e2[i]; } env->ReleaseFloatArrayElements(coef2, c2, 0 ); env->ReleaseIntArrayElements(expn2, e2, 0 ); Polyn pa=CreatePolyn(n1,c11,e11); Polyn pb=CreatePolyn(n2,c22,e22); Polyn hf,pf; Polyn qa=pa->next; Polyn qb=pb->next; hf=(Polyn)malloc(sizeof(struct Polynomial));//建立头结点 hf->next=NULL; for(;qa;qa=qa->next){ for(qb=pb->next;qb;qb=qb->next){ pf=(Polyn)malloc(sizeof(struct Polynomial)); pf->coef=qa->coef*qb->coef; pf->expn=qa->expn+qb->expn; Insert(pf,hf); //调用Insert函数以合并指数相同的项}}return PrintPolyn(hf,env); }
编译PolynomialCaculator.cpp,将会获得PolynomialCaculator.dll文件,将该文件复制粘贴到java工程的根目录,这个目录非常重要,不要弄错。为了防止大家出错,贴出我的工程目录截图
6) 将你的Java代码跑起来
即调用InvokerHelper类里定义的方法,只要像调用普通的额Java类的方法一样就可以了
这里将我写的一元稀疏多项式的界面代码是功能实现也贴出来:
/src/view/CalculatorUI.java
package view;import java.awt.Dimension;import java.awt.FlowLayout;import java.awt.Font;import java.awt.GridLayout;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JTextArea;import helper.InvokerHelper;public class CalculatorUI extends JFrame implements ActionListener {private JTextArea answerText;private JPanel panel;private String[] btString = { "^", "(", ")", "计算", "7", "8", "9", "-", "4", "5", "6", "+", "1", "2", "3", "0", "C","x", "*" };// 存储两个多项式的系数与指数private float[] coef1;private int[] expn1;private float[] coef2;private int[] expn2;private String operator;public CalculatorUI() {// (6x-3-x+4.4x2-1.2x9) (-6x-3+5.4x2-x2+7.8x15) sssssssssssanswerText = new JTextArea(1, 37);GridLayout layout = new GridLayout(5, 4, 4, 4);panel = new JPanel(layout);panel.setPreferredSize(new Dimension(450, 200));this.setLayout(new FlowLayout());this.setTitle("一元稀疏多项式计算器");answerText.setFont(new Font("TimesRoman", Font.BOLD, 15));for (int i = 0; i < btString.length; i++) {JButton bt = new JButton(btString[i]);bt.addActionListener(this);panel.add(bt);}this.add(answerText);this.add(panel);Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();int width = screenSize.width;int height = screenSize.height;this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setSize(450, 270);this.setResizable(false);this.setLocation(width / 2 - 215, height / 2 - 165);this.setVisible(true);}@Overridepublic void actionPerformed(ActionEvent event) {String c = event.getActionCommand();switch (c) {case "计算":analyseFormular(answerText.getText());break;case "C":answerText.setText("");break;default:answerText.append(c);}}private void analyseFormular(String s) {// (2x^2+3x^3)+(3x^3+4x^4)if (!verifyFormula(s)) {JOptionPane.showMessageDialog(this, "式子不匹配,式子应符合(多项式1)+或-或*(多项式2)");return;}getOperator(s);getArrayData(s);Calculate();}private void Calculate() {String answer;switch (operator) {case "+":// getAnswer(answer)System.out.println("加法");answer = InvokerHelper.AddPolyn(coef1.length, coef1, expn1, coef2.length, coef2, expn2);answerText.setText(getAnswer(answer));break;case "-":System.out.println("减法");answer = InvokerHelper.SubtractPolyn(coef1.length, coef1, expn1, coef2.length, coef2, expn2);answerText.setText(getAnswer(answer));break;case "*":System.out.println("乘法");answer = InvokerHelper.MultiplyPolyn(coef1.length, coef1, expn1, coef2.length, coef2, expn2);answerText.setText(getAnswer(answer));break;}}private String getAnswer(String answer) {StringBuilder result = new StringBuilder("");int i = 0;if (answer.length() > 0)for (i = 0; i < answer.length() && ((int) answer.charAt(i)) != 254; i++) {if (answer.charAt(i) == 'X' || answer.charAt(i) == '^' || answer.charAt(i) == '+'|| answer.charAt(i) == '-' || answer.charAt(i) == '.') {result.append(answer.charAt(i));System.out.print("," + answer.charAt(i));} else {result.append((int) answer.charAt(i));System.out.print("," + (int) answer.charAt(i));}}elseresult.append("0");return result.toString();}private void getOperator(String s) {if (s.contains(")+("))operator = "+";else if (s.contains(")-("))operator = "-";else if (s.contains(")*("))operator = "*";}private void getArrayData(String s) {// 获得两个多项式String forArr[] = s.split("\\)([+-]|\\*)\\(");String xiang = "((-?[0-9]+\\.?[0-9]*)|-)?x(\\^-?[0-9]+)?\\b|-?[0-9]+\\.?[0-9]*\\b";// 多项式每一项的正则表达式Pattern pattern = Pattern.compile(xiang);Matcher matcher;String[] arr1;String[] arr2;int num1 = 0;int num2 = 0;matcher = pattern.matcher(forArr[0]);while (matcher.find()) {num1++;}matcher = pattern.matcher(forArr[1]);while (matcher.find()) {num2++;}coef1 = new float[num1];expn1 = new int[num1];coef2 = new float[num2];expn2 = new int[num2];arr1 = new String[num1];arr2 = new String[num2];matcher = pattern.matcher(forArr[0]);int i = 0;while (matcher.find()) {arr1[i] = matcher.group();i++;}i = 0;matcher = pattern.matcher(forArr[1]);while (matcher.find()) {arr2[i] = matcher.group();i++;}String[] str;for (i = 0; i < arr1.length; i++) {System.out.println(arr1[i]);if (arr1[i].equals("x")) {coef1[i] = 1;expn1[i] = 1;} else if (arr1[i].equals("-x")) {coef1[i] = -1;expn1[i] = 1;} else if (!arr1[i].contains("x")) {// 整数coef1[i] = Float.parseFloat(arr1[i]);expn1[i] = 0;} else if (arr1[i].endsWith("x") && !arr1[i].contains("^")) {// 2x,3x这种形式coef1[i] = Float.parseFloat(arr1[i].replace("x", ""));expn1[i] = 1;} else if (arr1[i].startsWith("x") && arr1[i].contains("^")) {// x^3这种形式coef1[i] = 1;expn1[i] = Integer.parseInt(arr1[i].replace("x^", ""));} else {str = arr1[i].split("x\\^");if (str[0].equals("-"))coef1[i] = -1;elsecoef1[i] = Float.parseFloat(str[0]);expn1[i] = Integer.parseInt(str[1]);}System.out.println("系数:指数=" + coef1[i] + "," + expn1[i]);}for (i = 0; i < arr2.length; i++) {System.out.println(arr2[i]);if (arr2[i].equals("x")) {coef2[i] = 1;expn2[i] = 1;} else if (arr2[i].equals("-x")) {coef2[i] = -1;expn2[i] = 1;} else if (!arr2[i].contains("x")) {// 整数coef2[i] = Float.parseFloat(arr2[i]);expn2[i] = 0;} else if (arr2[i].endsWith("x") && !arr2[i].startsWith("x")) {// 2x,3x这种形式coef2[i] = Float.parseFloat(arr2[i].replace("x", ""));expn2[i] = 1;} else if (arr2[i].startsWith("x") && arr2[i].contains("^")) {// x^3这种形式coef2[i] = 1;expn2[i] = Integer.parseInt(arr2[i].replace("x^", ""));} else {str = arr2[i].split("x\\^");if (str[0].equals("-"))coef2[i] = -1;elsecoef2[i] = Float.parseFloat(str[0]);expn2[i] = Integer.parseInt(str[1]);}System.out.println("系数:指数=" + coef2[i] + "," + expn2[i]);}System.out.println("第一个多项式:");for (i = 0; i < coef1.length; i++)System.out.println(coef1[i] + ":" + expn1[i]);System.out.println("第二个多项式:");for (i = 0; i < coef2.length; i++)System.out.println(coef2[i] + ":" + expn2[i]);}// 验证表达式是否正确private boolean verifyFormula(String s) {boolean b = false;String duoxiangshi = "\\((([+-]?[0-9]+\\.?[0-9]*)|(([+-]?[0-9]+\\.?[0-9]*)|-)*x(\\^-?[0-9]+)?)(([+-])(([0-9]+\\.?[0-9]*)|(([0-9]+\\.?[0-9]*)|-)*x(\\^-?[0-9]+)?))*\\)";String regex = duoxiangshi + "([+-]|\\*)" + duoxiangshi;Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(s);b = matcher.matches();return b;}}这时一个有图形界面的一元稀疏多项式就完成了。
我在写这个小项目时候遇到的其他问题还包括
1、用正则表达式解析字符串,关于正则表达式,如果大家没有接触过,推荐给大家一个网址,非常有用
http://deerchao.net/tutorials/regex/regex.htm#howtouse
2、dll中C的返回值类型和java的接收的类型,这个对于刚接触java的jni的新手来说也是一个很头疼的问题。
3、在学习jni的过程中,还了解到可以用java封装好的jna,jna比jni的编程过程更佳简易
感悟:
写这个带图形界面的一元稀疏多项式计算器,完全只是处于感兴趣。本来是一个难度系数最低的课设,但后来脑洞大开想加入界面。但由于没学过用C写界面,而自己又有一定的swing编程基础,之前也听过不同语言混合开发一个程序。于是便开始在网上搜索资料。由此便一发不可收拾了,时时刻刻都在弄这个,因为领悟能力有限,有四五天是熬夜熬到凌晨三四点,最终经过四五天才完成这个作业。写完这个小项目,满满的成就感。希望大家不要被遇到的困难击退,坚持下来,总会有收获的
- 用java的jni调用C语言的API,实现带图形界面的一元稀疏多项式计算器
- 链表一元多项式计算器的实现(Java语言描述)
- 用链表实现一元稀疏多项式的相加
- 一元稀疏多项式计算器:一次数据结构实验的题目
- 设计一个一元稀疏多项式简单的加减法计算器
- 设计一个一元稀疏多项式简单的加减法计算器
- 一元稀疏多项式计算器
- 一元稀疏多项式计算器
- C语言实现一元多项式的加减运算
- C语言:用链表实现一元多项式的加法
- 一元多项式的乘法运算(C语言)实现
- c语言一元多项式的相加
- 一元多项式的实现
- 一元稀疏多项式加减法计算器
- [C/C++]OJ练习题:一元稀疏多项式计算器
- 一元多项式求和的实现
- PAT 3-04 一元多项式的乘法与加法运算(C语言实现)
- 华为面试题:一元多项式的化简 C语言实现源码
- 23种设计模式与《Head First设计模式》推荐
- 即时通讯之Socket.IO的学习,及使用nodejs 搭建websocket 聊天室
- 编译安装zabbix error: MySQL library not found
- 【腾讯开放平台】Android、IOS实现指定QQ临时会话功能
- FillBlankView:基于EditText的Android自定义补全信息控件,轻松高仿手机支付宝数字密码输入验证
- 用java的jni调用C语言的API,实现带图形界面的一元稀疏多项式计算器
- PHP调试配置
- Android:添加自己的应用到“分享”->"发送文件"选项
- wax lua 简介
- SoapUI 收邮件代码 (修改版)
- 派生类重写父类方法
- Java操作Excel文件以及在Android中的应用
- CC2640 广播数据构成分析
- LINUX 搭建apache ftpserver