MinGW-GCC 如何编译JNI程序进阶

JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少要保证本地代码能工作在任何Java 虚拟机环境下。

安装mingw-w64

因为我电脑是64位的,所以安装64位mingw,这点一定要注意
下载地址:https://sourceforge.net/projects/mingw-w64/

MinGW-GCC 如何编译JNI程序进阶_第1张图片

将mingw64\bin目录添加到Path环境变量

编译jni

MinGW-GCC 如何编译JNI程序进阶_第2张图片
1、Calculation.java

public class Calculation {
    static {
        System.loadLibrary("Calculation");
    }

    public native int add(int a, int b);

    public native int sub(int a, int b);

    public native int mul(int a, int b);

    public native int div(int a, int b);

    public static void main(String args[]) {        
        Calculation calc = new Calculation();       
        System.out.println("Java call cpp dll calculation result:" + calc.add(2,4));
    }
}

2、javac Calculation.java
javah Calculation
生成Calculation.h文件,不要修改此文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Calculation */

#ifndef _Included_Calculation
#define _Included_Calculation
#ifdef __cplusplus
extern "C" {
#endif
/* * Class: Calculation * Method: add * Signature: (II)I */
JNIEXPORT jint JNICALL Java_Calculation_add
  (JNIEnv *, jobject, jint, jint);

/* * Class: Calculation * Method: sub * Signature: (II)I */
JNIEXPORT jint JNICALL Java_Calculation_sub
  (JNIEnv *, jobject, jint, jint);

/* * Class: Calculation * Method: mul * Signature: (II)I */
JNIEXPORT jint JNICALL Java_Calculation_mul
  (JNIEnv *, jobject, jint, jint);

/* * Class: Calculation * Method: div * Signature: (II)I */
JNIEXPORT jint JNICALL Java_Calculation_div
  (JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

3、实现h文件声明的方法
Calculation.cpp

#include "Calculation.h"

JNIEXPORT jint JNICALL Java_Calculation_add
  (JNIEnv *, jobject obj, jint a, jint b)
{
    return (a+b);
}

JNIEXPORT jint JNICALL Java_Calculation_sub
  (JNIEnv *, jobject obj, jint a, jint b)
{
    return (a-b);
}

JNIEXPORT jint JNICALL Java_Calculation_mul
  (JNIEnv *, jobject obj, jint a, jint b)
{
    return (a*b);
}

JNIEXPORT jint JNICALL Java_Calculation_div
  (JNIEnv *, jobject obj, jint a, jint b)
{
    return (a/b);
}

4、编译cpp文件生成动态链接库Calculation.dll
gcc -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 -shared -o Calculation.dll Calculation.cpp

5、java Calculation

传递对象
TransferObject.java

public class TransferObject {
    static {
        System.loadLibrary("TransferObject");
    }

    public native String getString(String str);

    public native int[] getArrayData(int[] arr);

    public static void main(String args[]) {
        TransferObject calc = new TransferObject();
        System.out.println(calc.getString("传递String对象"));
        int[] arr = new int[10];
        for (int i = 0; i < 10; i++) {
            arr[i] = i;
        }
        arr = calc.getArrayData(arr);
        for (int i = 0; i < 10; i++) {
            System.out.println(arr[i]);
        }
    }
}

TransferObject.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TransferObject */

#ifndef _Included_TransferObject
#define _Included_TransferObject
#ifdef __cplusplus
extern "C" {
#endif
/* * Class: TransferObject * Method: getString * Signature: (Ljava/lang/String;)Ljava/lang/String; */
JNIEXPORT jstring JNICALL Java_TransferObject_getString
  (JNIEnv *, jobject, jstring);

/* * Class: TransferObject * Method: getArrayData * Signature: ([I)[I */
JNIEXPORT jintArray JNICALL Java_TransferObject_getArrayData
  (JNIEnv *, jobject, jintArray);

#ifdef __cplusplus
}
#endif
#endif

TransferObject.cpp

#include "TransferObject.h"
#include <jni.h>
#include <stdio.h>

JNIEXPORT jstring JNICALL Java_TransferObject_getString
(JNIEnv *env, jobject obj, jstring arg){
    //Get the native string from java String
    const char *nativeString = env->GetStringUTFChars(arg, 0);
    printf("%s", nativeString);
    //DON'T FORGET THIS LINE!!!
    env->ReleaseStringUTFChars(arg, nativeString);
    return arg;
}

JNIEXPORT jintArray JNICALL Java_TransferObject_getArrayData
(JNIEnv *env, jobject  obj, jintArray args){
    jint buf[10];
    jint i;
    env->GetIntArrayRegion(args, 0, 10, buf);
    jint j=0;
    for (i = 0; i < 10; i++) {
        j=buf[i];
        j*=j;
        buf[i]=j;
    }
    env->SetIntArrayRegion(args, 0, 10, buf);
    return args;
}

gcc -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 -shared -o TransferObject.dll TransferObject.cpp

基础HelloWorld参考
http://blog.csdn.net/luo_deng/article/details/11030905

tip:如果你使用eclipse-cpp Build项目时提示Program “make” is not found in PATH的错误
把项目删除,重新建立就不会出错了

你可能感兴趣的:(java,jni)