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