Android Jni 注册方法。以及在eclipse作为第三方so的使用

xiaoxiao2021-02-27  341

jni的整个过程分为几个步骤(整个工程较大,且还没有完成,无法整个贴出来,且也懒得整成一个小工程故而就贴个代码的节要吧。)

          1. java 类,2, h文件生成。3.c++文件。4. Android.mk, 5. 加入到系统以供esclipse调试时使用

1.java类,这个网上有无数的说明,简单的给一个例子。

          package com.iac.diagj.utils;

          public class DiagJni {               static{                   System.loadLibrary("diagjni");               }

              public static native int VerRead(char[] Buf);     public static native String VerRead();     public native int VerRead(byte[] Buf);     public native int VerRead(int n); //      public native String VerRead(String s);

        }

         注:这里如果给的是static函数,以及成员函数,生成的h文件,以及c++文件的参数是有区别的,我在调试时随意改了,没有注意一起改动,导致很头疼( env->RegisterNatives老是失败,提示找不到函数)直到最后比较生成的h文件是才明白。

2. h文件生成。

    找到esclipse的bin\classes目录。执行:

         \bin\classes>javah -d xxx com.iac.diagj.utils.DiagJni

         -d xxx表示目标文件目录,可以不要直接到当前目录再手工拷贝。

3. c++文件

    这里有两种方式:

         1, 直接送生成的头文件的函数名,实现响应的函数就好了。但是这样导致有一点风吹草动,就好对一大堆名字,不直观。不建议。

         2..使用注册方式,这个也没什么,只是要仔细一点参数不要搞错了,最好是从生产的头文件的Signature:行拷贝。

          这里贴出的示例包含了以上两种方式。DiagJniLog.h只是一个LOGE等的定义,就不贴了。

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <jni.h> #include <cutils/log.h> #include "com_iac_diagj_utils_DiagJni.h" #include "DiagJniLog.h" #define abs(a) (((a) > 0) ? (a) : (0-(a))) #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) > (b)) ? (b) : (a)) #define swap(a,b) do{(a) ^= (b); (b) ^= (a); (a) ^= (b);}while(0) static char JniVersion[] = "JniVer-V1.01"; /* * Class:     com_iac_diagj_utils_DiagJni * Method:    VerRead * Signature: ([C)I */ JNIEXPORT jint JNICALL Java_com_iac_diagj_utils_DiagJni_VerRead___3C  (JNIEnv * env, jclass jcls, jcharArray ver) jsize jLen  = env->GetArrayLength(ver);  LOGI("VerBuf len: %d, Ver:%s", jLen, JniVersion); jLen = min(jLen-1, strlen(JniVersion)); jchar* j_version = (jchar*)calloc(sizeof(jchar), jLen); for(int i=0; i <= jLen; i++){    j_version[i] =  (jchar) JniVersion[i]; // LOGI("VerBuf X", j_version[i]); } env->SetCharArrayRegion(ver, 0, jLen , j_version); free(j_version); return jLen; }   /* * Class:     com_iac_diagj_utils_DiagJni * Method:    VerRead * Signature: ([B)I */ JNIEXPORT jint JNICALL Java_com_iac_diagj_utils_DiagJni_VerRead___3B  (JNIEnv * env, jobject jobj, jbyteArray ver) { jsize jLen  = env->GetArrayLength(ver);  LOGI("VerBuf len: %d, Ver:%s", jLen, JniVersion); jLen = min(jLen-1, strlen(JniVersion));    env->SetByteArrayRegion(ver, 0, jLen, (const jbyte *)JniVersion); return jLen; }    /* * Class:     com_iac_diagj_utils_DiagJni * Method:    VerRead * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_iac_diagj_utils_DiagJni_VerRead__  (JNIEnv * env, jclass jcls) { LOGI("Ver:%s", JniVersion); return env->NewStringUTF(JniVersion); } /* * Class:     com_iac_diagj_utils_DiagJni * Method:    VerRead * Signature: (I)I */ static jint VerRead__I(JNIEnv * env, jobject jobj, jint n) { LOGI("Ver:%s", JniVersion); return strlen(JniVersion); } /* * Class:     com_iac_diagj_utils_DiagJni * Method:    VerRead * Signature: (Ljava/lang/String;)Ljava/lang/String; */ static jstring VerRead__S(JNIEnv * env, jobject jobj, jstring s) { LOGI("Ver:%s", JniVersion); return env->NewStringUTF(JniVersion); } JNINativeMethod nativeMethod[] = { {"VerRead" ,"(I)I"              , (void*)VerRead__I }, {"VerRead"      ,"(Ljava/lang/String;)Ljava/lang/String;" , (void*)VerRead__S  }, }; JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {    JNIEnv *env;    if (jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {        return -1;    }    LOGE("JNI_OnLoad comming %d", __LINE__);      jclass clz = env->FindClass("com/iac/diagj/utils/DiagJni");    env->RegisterNatives(clz, nativeMethod, sizeof(nativeMethod)/sizeof(nativeMethod[0]));    return JNI_VERSION_1_4; }

4.Android.mk

   这个就是照葫芦画瓢了。

LOCAL_PATH:= $(call my-dir) # 一个完整模块编译 include $(CLEAR_VARS) LOCAL_LDLIBS := -llog LOCAL_SRC_FILES:=DiagJni.cpp LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) LOCAL_MODULE := libdiagjni LOCAL_SHARED_LIBRARIES := libutils LOCAL_PRELINK_MODULE := false LOCAL_MODULE_TAGS :=optional include $(BUILD_SHARED_LIBRARY) 5.esclipse调试:

这个问题比较麻烦,网上说啥的都有,一会找不到so,一会命名在响应的目录下边,但是就是找不到,最后再corelog里边找到了一些提示,方法如下:

(这个是android 6.01的版本的真机别的机器版本可能不同)。

adb push Android\out\target\product\msm8953_64\system\lib64\libdiagjni.so /vendor/lib64/libdiagjni.so adb shell chmod 777 /vendor/lib64/libdiagjni.so

转载请注明原文地址: https://www.6miu.com/read-1258.html

最新回复(0)