自学内容网 自学内容网

android应用调用c语言的so库

android应用调用c语言的so库,可以将c代码放在android工程里直接ndk编译,或者外部一个so库,ndk编一个调用so的桥接库。普通的c函数java代码不能直接调用,桥接的虚函数不可少,所以此处仅记录一下桥接函数。有的固定路径的项目,会把桥接函数也固化在so里。

第一步在build.gradle里增加ndk编译脚本

 externalNativeBuild {
        ndkBuild {
            path file("src/main/jni/Android.mk")
        }
    }

第2步,编辑脚本

#表示Android.mk所在目录
LOCAL_PATH := $(call my-dir)
#CLEAR_VARS变量指向特殊 GNU Makefile,用于清除部分LOCAL_变量
include $(CLEAR_VARS)
APP_ABI := arm64-v8a

#LOCAL_SHARED_LIBRARIES := ../jniLibs/arm64-v8a/libfwupdate
LOCAL_LDLIBS := -L/home/qiaozc/StudioProjects/emv/app/src/main/jniLibs/arm64-v8a -lfwupdate
# 添加对日志库的引用
LOCAL_LDLIBS += -llog

#模块名称
LOCAL_MODULE    := detectemv
#构建系统用于生成模块的源文件列表
LOCAL_SRC_FILES := detectemv.c

#BUILD_SHARED_LIBRARY 表示.so动态库
#BUILD_STATIC_LIBRARY 表示.a静态库
include $(BUILD_SHARED_LIBRARY)

第3步,编写桥接c文件

#include <android/log.h>
#include <jni.h>
#include <string.h>
#include "fwupdate.h"

#define LOG_TAG "DEMO"

#define LOGD(fmt, ...)                                                         \
  __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##__VA_ARGS__)


JNIEXPORT jint JNICALL Java_com_test_nativelib_FwUpdateLib_detectEmv(
        JNIEnv *env, jobject thiz, jbyteArray jOutCard, jbyteArray jOutDate) {
    LOGD("In card detected callback");
    char cardNumber[64] = {0};
    char expireDate[8] = {0};
    int RetVal = detectEmv(cardNumber, expireDate);
    LOGD("RetVal=%s date=%s ", cardNumber, expireDate);
    int len = strlen(cardNumber);
    // 把elems复制给arr,从第0位开始,长度位len
    (*env)->SetByteArrayRegion(env, jOutCard, 0, len, cardNumber);
    len = strlen(expireDate);
    (*env)->SetByteArrayRegion(env, jOutDate, 0, len, expireDate);
}

第4步,我这里桥接就是将原so库的函数在这里调用将值再传出去,引用了需要的函数声明的头文件,自己可以造一个fwupdate.h

#ifndef VALIDATOR_FWUPDATE_H
#define VALIDATOR_FWUPDATE_H

int detectEmv(char *cardNumber, char *expireDate);

#endif //VALIDATOR_FWUPDATE_H

第5步,将桥接函数再映射到java里

package com.test.nativelib;

public class FwUpdateLib {
    static {
        System.loadLibrary("detectemv");
    }

    native public int detectEmv(byte[] cardNumber, byte[] expireDate);

}

后面在java里就可以正常当java函数调用了


原文地址:https://blog.csdn.net/qiaozhangchi/article/details/143807530

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!