zoukankan      html  css  js  c++  java
  • Android JNI 由C/C++本地代码向Java层传递数据

    最近做的Android项目需要调用C代码,进行串口通信及与硬件设备通信,因此要用到JNI,其中本地代码需要向Java层返回三个参数,分别为

    参数一:int型;

    参数二: 通信指令,本地代码中为unsigned char[]型,返回unsigned char[]、int[]都可以,能直接将数据转换为16进制字符串最好(Android界面上要显示的就是数组每一位的16进制值);

    参数三:同参数二。

    具体的实现方式有两种。

    第一种是C代码获取Java属性参数,本地修改参数值。

    第二种是将三个参数定义为对象,作为函数返回值返回给Java层。

     

    第二种方法的实现,这里定义了一个对象数组,满足参数二、三的要求,即返回int型数组,而对于参数一来说有些浪费。

    Java 代码:

    package com.fansen.hellojni;
    
    import android.annotation.SuppressLint;
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.TextView;
    
    public class MainActivity extends Activity {
    
        @SuppressLint("DefaultLocale")
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            TextView  tv = new TextView(this);
            tv.setText( "Hello World!" );
            
            DiskInfo[] infos = stringFromJNI();
            for (int i = 0; i < infos.length; i++) {

            Log.i("TAG", "infos[" + i + "].data: " + infos[i].data);
            Log.i("TAG", "infos[" + i + "].value: " + infos[i].value);
            Log.i("TAG", "infos[" + i + "].number: " + infos[i].number);

            }
    
            setContentView(tv);
        }
        
        public native DiskInfo[]  stringFromJNI();
    
        static {
            System.loadLibrary("hello-jni");
        }
    
    }
    
    class DiskInfo{
        public int data;
        public int value;    
        public int number;    
    }

    C代码:

    #include <string.h>
    #include <jni.h>
    
    typedef struct{
        int data;
        int value;
        int number;
    } DiskInfo;
    
    jobjectArray  Java_com_fansen_hellojni_MainActivity_stringFromJNI( JNIEnv* env, jobject thiz )
    {
        jclass clsDiskInfo = (*env)->FindClass(env, "com/fansen/hellojni/DiskInfo");
        jobjectArray infos = (*env)->NewObjectArray(env, 10, clsDiskInfo, NULL);
    
        jfieldID dataID = (*env)->GetFieldID(env, clsDiskInfo, "data", "I");
        jfieldID valueID = (*env)->GetFieldID(env, clsDiskInfo, "value", "I");
        jfieldID numberID = (*env)->GetFieldID(env, clsDiskInfo, "number", "I");
        jmethodID consID = (*env)->GetMethodID(env, clsDiskInfo, "<init>", "()V");
    
        unsigned char send[10] = {0xFF,0x1F,0x07,0x08,0x00,0x00,0x01,0x02};
    
        int sendcopy[10] = {0};
        int j;
        for(j = 0; j <= 8; j++){
            sendcopy[j] = send[j];  //模拟C代码值变化
        }
    
        int i;
        jobject obj;
        for(i = 0; i < 10; i++){
            obj = (*env)->NewObject(env, clsDiskInfo, consID);
            (*env)->SetIntField(env, obj, dataID, (jint)i);
            (*env)->SetIntField(env, obj, valueID, (jint)sendcopy[i]);
            (*env)->SetIntField(env, obj, numberID, (jint)sendcopy[i]); 
         (
    *env)->SetObjectArrayElement(env, infos, i, obj);
      }
      return infos;
    }
  • 相关阅读:
    1216
    构建之法 1 2 3
    复利计算
    实验总结
    0916编译原理第二次上机作业
    0909第一次作业
    linux 更新jdk
    Java中使用OpenSSL生成的RSA公私钥进行数据加解密
    quartz定时任务时间表达式说明
    IntelliJ IDEA使用说明
  • 原文地址:https://www.cnblogs.com/fansen/p/4845086.html
Copyright © 2011-2022 走看看