当前位置: 首页 > article >正文

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函数调用了


http://www.kler.cn/a/396505.html

相关文章:

  • 数据分析-48-时间序列变点检测之在线实时数据的CPD
  • QT QLineEdit失去焦点事件问题与解决
  • 论文 | On Second Thought, Let’s Not Think Step by Step!
  • Uniapp踩坑input自动获取焦点ref动态获取实例不可用
  • Flutter:input输入框
  • NPOI 实现Excel模板导出
  • 专业140+总分400+南京大学851信号与系统考研经验南大电子信息通信工程集成电路,真题,大纲,参考书。
  • 华为云前台用户可挂载数据盘和系统盘是怎么做到的?
  • 计算机组成原理对于学习嵌入式开发的意义
  • jmeter并发测试
  • 【已解决】 Tomcat10.1.x使用JSTL标签库
  • Android音视频直播低延迟探究之:WLAN低延迟模式
  • 保存pytest的执行日志;在日志中显示当前是第几次执行
  • 基于 Vue 实现简易 Vue-Router
  • GESP4级考试语法知识(贪心算法(五))
  • [白月黑羽]关于仿写类postman功能软件题目的解答
  • Leetcode 每日一题 125.验证回文串
  • PLC如何支持GEM300标准?SECS/GEM通讯协议
  • 卷积层(CNN)全面解析
  • 如何使用 python 中的 Pillow 创建可自定义的图标生成器
  • 软件工程视角:Git 基础与实践
  • NLP开发常见问题
  • 微信小程序之路由跳转传数据及接收
  • JWTUtil工具类
  • 加深深度学习矩阵计算理解--用人类直觉 走进线性代数(非应试)
  • 自存 关于RestController请求传参数 前端和后端相关