java调用c++带返回值

时间:2022-01-30 00:16:15

java通过jni调用c++,其中涉及到的基本类型会不大一样,int 、float、double可以强转,但是数组和String类型基本上要用过

java  String-->jni  jstring-->c++  string类型转换,具体详细在这篇博客写的比较清楚https://blog.csdn.net/u011974987/article/details/52743495,看下面基本粒子,在java中写native的方法:

public class JniTest {
    public native  String getString(String str);
    public native  int   getInteger(int i);
    public native  int[]  getArray(int[] arr);
    public native  double  getDouble(double d);
}

然后调用javah生成c++头文件,下面是生成的c++头文件:

#include "jni.h"
/* Header for class com_alibaba_jni_JniTest */

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


/*
 * Class:     com_alibaba_jni_JniTest
 * Method:    getInteger
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_alibaba_jni_JniTest_getInteger
        (JNIEnv *, jobject, jint);

/*
 * Class:     com_alibaba_jni_JniTest
 * Method:    getArray
 * Signature: ([I)[I
 */
JNIEXPORT jintArray JNICALL Java_com_alibaba_jni_JniTest_getArray
        (JNIEnv *, jobject, jintArray);

/*
 * Class:     com_alibaba_jni_JniTest
 * Method:    getDouble
 * Signature: (D)D
 */
JNIEXPORT jdouble JNICALL Java_com_alibaba_jni_JniTest_getDouble
        (JNIEnv *, jobject, jdouble);

#ifdef __cplusplus
}
#endif
#endif

源文件实现:

#include "jni.h"
#include <iostream>
#include "com_alibaba_jni_JniTest.h"
using namespace  std;
JNIEXPORT jstring JNICALL Java_com_alibaba_jni_JniTest_getString(JNIEnv * env, jobject jobj, jstring jstr){

    const char* str;
    jboolean f= false;
    str = env->GetStringUTFChars(jstr, &f);
    if(str == NULL) {
        return NULL;
    }

    //env->ReleaseStringUTFChars(jstr, str);
    //std::cout << str << std::endl;
  // 返回一个字符串
  //    char* tmpstr = "return string succeeded";
   jstring rtstr = env->NewStringUTF(str);
    return rtstr ;
}

JNIEXPORT jint JNICALL Java_com_alibaba_jni_JniTest_getInteger(JNIEnv * env, jobject job, jint i){
    int rtn = (int) i*2;

    return (jint) rtn ;

}

JNIEXPORT jdouble JNICALL Java_com_alibaba_jni_JniTest_getDouble
        (JNIEnv * env, jobject jb, jdouble d){
    double rtn = (int) d*2;

    return (jint) rtn ;

    return d*2;

}

JNIEXPORT jintArray JNICALL Java_com_alibaba_jni_JniTest_getArray
        (JNIEnv *env, jobject, jintArray arr){
    jboolean f= false;
    jint *elems = env->GetIntArrayElements(arr,&f);
    int len = env->GetArrayLength( arr);

    for (int i = 0; i < len; i++){
        elems[i] = elems[i]*3;
    }
    jintArray jint_arr = env->NewIntArray( len);
    env->ReleaseIntArrayElements( jint_arr, elems,1);
    return jint_arr;

}

用cmake打包生成dylib文件,我电脑是mac,其他系统可以是so以及dll文件,在java里面调用:

package com.alibaba.jni;

import java.util.Arrays;

public class App {
    public static void main(String[] args) {
        JniTest jni=new JniTest();
        int[] arr={1,2,3};
        System.out.println(jni.getDouble(10.0));
        System.out.println(jni.getInteger(2));
        System.out.println(jni.getString("abcde"));
        System.out.println(Arrays.toString(jni.getArray(arr)));

    }
}

结果:

20.0
4
abcde

[3, 6, 9]

这种实在是太过于方便,可以各种调用,想想以后做一些机器学习任务,工程方面再也不是问题。