调用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() {
@Override
public 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_H
int 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用%f
LOGI("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用%f
LOGI("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用%f
LOGI("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);
}