JNI示例

java调用C

java中的native方法声明
public class JniController {

    {
        System.loadLibrary("jniLib");
    }

    //计算两数之和
    public native int sum(int x,int y);

    //处理字符串
    public native String sayHello(String s);

    //处理int数组
    public native int[] executeList(int[] intArray);

    //匹配字符串
    public native int checkPwd(String pwd);
}
C文件中方法的实现
#include <string.h>
#include <malloc.h>
#include "com_example_jnidemo_JniController.h"
#include <android/log.h>
#define LOG_TAG "TAG_JNI"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

/**
 * 将 jstring类型 转换成 char指针类型
 * */
char* _JString2CStr(JNIEnv* env, jstring jstr) {
    char *rtn = NULL;
    jclass clsstring = (*env)->FindClass(env, "java/lang/String");
    jstring strencode = (*env)->NewStringUTF(env, "GB2312");
    jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");
    jbyteArray barr = (jbyteArray) (*env)->CallObjectMethod(env, jstr, mid,
                                                            strencode); // String .getByte("GB2312");
    jsize alen = (*env)->GetArrayLength(env, barr);
    jbyte *ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
    if (alen > 0) {
        rtn = (char *) malloc(alen + 1); //"\0"
        memcpy(rtn, ba, alen);
        rtn[alen] = 0;
    }
    (*env)->ReleaseByteArrayElements(env, barr, ba, 0);
    return rtn;
}

/**
 * 操作int
 * */
JNIEXPORT jint JNICALL Java_com_example_jnidemo_JniController_sum
        (JNIEnv* jniEnv, jobject jobj, jint x, jint y){
    jint sum = x + y;
    return sum;
};

/**
 * 操作字符串
 * */
JNIEXPORT jstring JNICALL Java_com_example_jnidemo_JniController_sayHello
        (JNIEnv* jniEnv, jobject jobj, jstring jstr){

    char* cStr = "i am from c";

    //将 jString类型 转换成 char指针
    char* javaStr = _JString2CStr(jniEnv,jstr);

    //拼接字符串方法
    char* newStr = strcat(javaStr,cStr);

    return (*jniEnv)->NewStringUTF(jniEnv,newStr);
};

/**
 * 操作数组
 * */
JNIEXPORT jintArray JNICALL Java_com_example_jnidemo_JniController_executeList
        (JNIEnv* jniEnv, jobject jobj, jintArray jarray){

    //获取数组的长度
    jsize size = (*jniEnv)->GetArrayLength(jniEnv,jarray);

    //获取数组的地址(即 首元素地址)
    jint* arrayAddress = (*jniEnv)->GetIntArrayElements(
            jniEnv,
            jarray,
            JNI_FALSE // 不再创新创建数组
            );

    //遍历数组,操作其中的数据
    int i;
    for (i = 0; i < size; ++i) {
        *(arrayAddress+i) +=10;
        LOGD("遍历的item的值:%d",*(arrayAddress+i));
    }

    //释放资源,必须!否则操作可能不生效
    (*jniEnv)->ReleaseIntArrayElements(jniEnv,jarray,arrayAddress,0);

    return jarray;
}

/**
 * 验证字符串
 * */
JNIEXPORT jint JNICALL Java_com_example_jnidemo_JniController_checkPwd
        (JNIEnv* jniEnv, jobject jobj, jstring jstr){

    char* origin = "123456";

    //将用户输入的密码装换为char类型
    char* inputPwd = _JString2CStr(jniEnv,jstr);

    //比较两个字符串是否相等
    int result = strcmp(origin,inputPwd);

    //相等
    if(result==0){
        return 200;
    }
    //不相等
    else{
        return 400;
    }
};

C回调Java

java中的方法
public class CallJavaController {

    {
        System.loadLibrary("jniCCallJavaLib");
    }

    public native void callBackAdd();

    public native void callbackPrintString();

    public native void callbackSayHello();

	//以下三个方法 为C中要回调的方法
	
    public int add(int x,int y){
        Log.d("tag_jni","调用 add()   x:" + x + "   y:" + y);
        return x+y;
    }

    public void printString(String s){
        Log.d("tag_jni","C 中传递回来的字符串:" + s );
    }

    public static void sayHello(){
        Log.d("tag_jni","C 调用了java中的静态方法" );
    }
}
C文件对java方法的回调
#include "com_example_jnidemo_CallJavaController.h"
#include <android/log.h>
#define LOG_TAG "TAG_JNI"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

//实现在回调java方法的同时,向java层传递int参数
JNIEXPORT void JNICALL Java_com_example_jnidemo_CallJavaController_callBackAdd(JNIEnv* env, jobject jobj){

    //1.获取要调用的方法所归属的类
    char* classAddress = "com/example/jnidemo/CallJavaController";
    jclass jclazz = (*env)->FindClass(env,classAddress);

    //2.获取该类中的方法 (最后一个参数即 方法的签名 可通过 "javap -s [.class文件名]" 进行查看)
    jmethodID jmethodId = (*env)->GetMethodID(env,jclazz,"add","(II)I");

    //3. 实例化该类 (此处也可以直接使用传递过来的jobj,此处如此使用是为了展示该方法)
    jobject jobject1 = (*env)->AllocObject(env,jclazz);

    LOGD("value= %s","测试");

    //4.调用方法
    (*env)->CallIntMethod(env,jobject1,jmethodId,22,33);

};

//实现在回调java方法的同时,向java层传递字符串参数
JNIEXPORT void JNICALL Java_com_example_jnidemo_CallJavaController_callbackPrintString
        (JNIEnv* env, jobject jobj){

    //1.获取要调用的方法所归属的类
    char* classAddress = "com/example/jnidemo/CallJavaController";
    jclass jclazz = (*env)->FindClass(env,classAddress);

    //2.获取该类中的方法
    jmethodID jmethodId = (*env)->GetMethodID(env,jclazz,"printString","(Ljava/lang/String;)V");

    //3. 实例化该类 (此处也可以直接使用传递过来的jobj,此处如此使用是为了展示该方法)
    jobject jobject1 = (*env)->AllocObject(env,jclazz);

    //4.生成要传递的字符串
    jstring jstr = (*env)->NewStringUTF(env,"i am from c");

    //5.调用方法 (注意此处调用的是 '无参方法':CallVoidMethod )
    (*env)->CallVoidMethod(env,jobject1,jmethodId,jstr);

};

// 实现对java中静态方法的回调
JNIEXPORT void JNICALL Java_com_example_jnidemo_CallJavaController_callbackSayHello
        (JNIEnv* env, jobject jobj){

    //1.获取要调用的方法所归属的类的字节码
    char* classAddress = "com/example/jnidemo/CallJavaController";
    jclass jclazz = (*env)->FindClass(env,classAddress);

    //2.获取该类中的方法
    jmethodID jmethodId = (*env)->GetStaticMethodID(env,jclazz,"sayHello","()V");

    //3.调用方法 (注意此处传递的)
    (*env)->CallStaticVoidMethod(env,jclazz,jmethodId);
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值