调用Jni方法并传入 int, double, float, String类型的参数
本文介绍java层向jni层传递基本数据类型的参数,主要涉及到java层–>jni层–>c/c++层的数据转换,模拟了从java层到jni层再到C/C++层的调用流程。
1、java层声明native方法
/*** 两个数相加,然后把结果转换成String再返回来* @param a* @param b* @return*/public native String setIntParam(int a,int b);/*** 返回结果字符串* @param d1* @param d2* @return*/public native String setDoubleParam(double d1,double d2);/*** 返回结果字符串* @param f1* @param f2* @return*/public native String setFloatParam(float f1,float f2);/*** 在jni中把接收到的参数前面加上一个字符串再返回来* @param stringParam* @return*/public native String setStringParam(String stringParam);
2、在MainActivity中调用
// int类型相加
binding.btnSetInt.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Toast.makeText(MainActivity.this,setIntParam(4,5),Toast.LENGTH_SHORT).show();}
});// double类型相加
binding.btn2Double.setOnClickListener(view->{double a = 4.21d;double b = 5.12;Toast.makeText(MainActivity.this,setDoubleParam(a,b),Toast.LENGTH_SHORT).show();
});// double类型相加
binding.btnAddFloat.setOnClickListener(view->{float f1 = 2.3f;float f2 = 4.5f;String floatRet = setFloatParam(f1,f2);String finalRet = f1 + " + " + f2 + " = " + floatRet;Toast.makeText(MainActivity.this,finalRet,Toast.LENGTH_SHORT).show();
});// 在jni中把接收到的参数前面加上一个字符串再返回来
binding.btnSetStringParam.setOnClickListener(view->{String strParam = "java to c -> setParam";String strRet = setStringParam(strParam);Toast.makeText(this, strRet, Toast.LENGTH_SHORT).show();
});
3、C++层文件的定义(MyTask.h / MyTask.cpp)
//
// MyTask.h
// Created by lixm on 2024/9/4.
//
#ifndef NDKTEST_MYTASK_H
#define NDKTEST_MYTASK_Hint addInt(int a,int b);double addDouble(double a,double b);float addFloat(float a,float b);#endif //NDKTEST_MYTASK_H
//
// MyTask.cpp
// Created by lixm on 2024/9/4.
//
#include <iostream>
using namespace std;int addInt(int a,int b){cout << "in addInt() a = " << a << ", b = " << b << endl;return a + b;
}double addDouble(double a,double b){cout << "in addDouble() a = " << a << ", b = " << b << endl;return a + b;
}float addFloat(float a,float b){cout << "in addFloat() a = " << a << ", b = " << b << endl;return a + b;
}
4、jni层文件的定义
#include <jni.h>
#include <string>
#include "MyTask.h"
#include <iostream>#include <android/log.h>#define LOG_TAG "MyJNILog"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG ,__VA_ARGS__) // 定义LOGI类型
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG ,__VA_ARGS__) // 定义LOGD类型
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG ,__VA_ARGS__) // 定义LOGW类型
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG ,__VA_ARGS__) // 定义LOGE类型
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG ,__VA_ARGS__) // 定义LOGF类型extern "C"
JNIEXPORT jstring JNICALL
Java_com_hisign_ndktest_MainActivity_setIntParam(JNIEnv *env, jobject thiz, jint a, jint b) {// todo 这里模拟了数字转字符串,和字符串的拼接返回// int 和 jint可以直接互转int sum = addInt(a, b);char buf[100];sprintf(buf, "%d", sum); // 数组转字符串LOGI("strPre = %s", buf);// 直接返回计算结果的字符串//return (*env).NewStringUTF(buf);char *strPre = "result is : "; // 使用字符串字面量(不能被改变)char tmp[50]; // 定义一个临时的缓冲区strcpy(tmp, strPre); // 把字符串值拷贝到缓冲区里面strcat(tmp, buf); // 连接两个字符串//C字符串转java字符串return (*env).NewStringUTF(tmp);
}extern "C"
JNIEXPORT jstring JNICALL
Java_com_hisign_ndktest_MainActivity_setDoubleParam(JNIEnv *env, jobject thiz, jdouble a,jdouble b) {// todo 注意这里的format用%fLOGI("ina native , a = %f,b= %f", a, b);double sum = addDouble(a, b);LOGI("ina native , sum = %f", sum);char buf[100];sprintf(buf, "%f", sum); // todo 注意这里的format用%fLOGI("strPre = %s", buf);// 直接返回计算结果的字符串return (*env).NewStringUTF(buf);
}extern "C"
JNIEXPORT jstring JNICALL
Java_com_hisign_ndktest_MainActivity_setFloatParam(JNIEnv *env, jobject thiz, jfloat f1,jfloat f2) {LOGI("x = %f, y= %f", f1, f2);float sum = addFloat(f1, f2);char buf[100];sprintf(buf, "%f", sum); // float类型的结果转换为C字符串,format用%fLOGI("addFloat(),result = %s", buf);// 直接返回计算结果的字符串return (*env).NewStringUTF(buf);
}extern "C"
JNIEXPORT jstring JNICALL
Java_com_hisign_ndktest_MainActivity_setStringParam(JNIEnv *env, jobject thiz,jstring string_param) {// 创建一个C字符串char *strPre = "you input param is : ";// 把java的字符串转换为c的字符串const char *c_str = env->GetStringUTFChars(string_param, NULL);LOGI("c_str = %s", c_str);// 把两个C字符串连接在一起int len1 = strlen(strPre);int len2 = strlen(c_str);LOGI("len1 = %d, len2 = %d", len1, len2);char buf[len1 + len2 + 4];memset(buf, 0, sizeof(buf));strcpy(buf, strPre);strcat(buf, c_str);printf("result = %s", buf);LOGI("result = %s", buf);return (*env).NewStringUTF(buf);
}