JNI笔记

JNI笔记

  • 背景
  • Demo代码
    • JNI.java
    • MainActivity.java
    • Android.mk
    • Application.mk
    • com_stone_javacallc_JNI.h
    • javacallc.c
    • build.gradle

背景

在这里插入图片描述

Demo代码

代码结构
在这里插入图片描述

JNI.java

package com.stone.javacallc;

/**
 * Created by stoneWang
 * Created on 2024/1/16
 * java调用C
 */
public class JNI {

    {
        System.loadLibrary("javacallc");
    }
    /**
     * 让C代码做加法运算,把结果返回
     *
     * @param x
     * @param y
     * @return
     */
    public native int add(int x, int y);

    /**
     * 从Java传入字符串,C代码进行拼接
     *
     * @param s I am from java
     * @return  I am from java add I am from C
     */
    public native String sayHello(String s);

    /**
     * 让C代码给每个元素加上10
     *
     * @param intArray
     * @return
     */
    public native int[] increaseArrayEles(int[] intArray);
}

MainActivity.java

package com.stone.javacallc;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    private JNI jni;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        jni = new JNI();
    }

    public void add(View view) {
        int result = jni.add(99, 1);
        Log.e(MainActivity.class.getSimpleName(), "result:" + result);
    }

    public void string(View view) {
        String result = jni.sayHello("I am from java ");
        Log.e(MainActivity.class.getSimpleName(), "result:" + result);
    }

    public void array(View view) {

    }

    public void checkpw(View view) {

    }


}

Android.mk

LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE :=javacallc
LOCAL_SRC_FILES :=javacallc.c
include $(BUILD_SHARED_LIBRARY)

Application.mk

App_ABI:=all

com_stone_javacallc_JNI.h

在这里插入图片描述

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_stone_javacallc_JNI */

#ifndef _Included_com_stone_javacallc_JNI
#define _Included_com_stone_javacallc_JNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_stone_javacallc_JNI
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_stone_javacallc_JNI_add
  (JNIEnv *, jobject, jint, jint);

/*
 * Class:     com_stone_javacallc_JNI
 * Method:    sayHello
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jstring JNICALL Java_com_stone_javacallc_JNI_sayHello
  (JNIEnv *, jobject, jstring);

/*
 * Class:     com_stone_javacallc_JNI
 * Method:    increaseArrayEles
 * Signature: ([I)[I
 */
JNIEXPORT jintArray JNICALL Java_com_stone_javacallc_JNI_increaseArrayEles
  (JNIEnv *, jobject, jintArray);

#ifdef __cplusplus
}
#endif
#endif

javacallc.c

//
// Created by wanglei on 2024/1/16.
//
# include "com_stone_javacallc_JNI.h"
# include "string.h"

/**
 * 把一个jstring转换成一个c语言的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;
}

/**
 *
 * @param env
 * @param jobj
 * @param ji
 * @param jj
 * @return
 */
jint Java_com_stone_javacallc_JNI_add
        (JNIEnv *env, jobject jobj, jint ji, jint jj){
    int result = ji + jj;
    return result;
};


jstring Java_com_stone_javacallc_JNI_sayHello
        (JNIEnv *env, jobject jobj, jstring jstr){
    char* fromJava = _JString2CStr(env, jstr);
    char* fromc = "add I am from C";
    // 拼接函数strcat
    strcat(fromJava, fromc); // 把拼接的结果放在第一参数里面
    // 将char转为jstring
    return (*env)->NewStringUTF(env, fromJava);
};

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

    defaultConfig {
        applicationId "com.stone.javacallc"
        minSdkVersion 26
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        ndk{
            moduleName "javacallc"
            abiFilters "armeabi", "armeabi-v7a", "arm64-v8a" // cpu类型
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        ndkBuild {
            path "src/main/jni/Android.mk"
        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/329029.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql常见的需求,对于关键字的使用

如何使用MySQL将列数据转化为逗号分隔的形式。我们可以使用内置函数GROUP_CONCAT()来实现这个功能 如何使用MySQL将列数据转化为逗号分隔的形式。我们可以使用内置函数GROUP_CONCAT()来实现这个功能&#xff0c;也可以根据实际需求自定义一个函数。这种技术在一些需要对数据进…

架构师之超时未支付的订单进行取消操作的几种解决方案

今天给大家上一盘硬菜&#xff0c;并且是支付中非常重要的一个技术解决方案&#xff0c;有这块业务的同学注意自己尝试一把哈&#xff01; 一、需求如下&#xff1a; 生成订单30分钟未支付&#xff0c;自动取消 生成订单60秒后,给用户发短信 对上述的需求&#xff0c;我们给…

leetcode—矩阵

1 矩阵置零 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]] 方法一&#xf…

知识库建设教程来啦,赶紧收藏起来

播种知识&#xff0c;收获效率。知识库&#xff0c;这个企业内部服务的“大百科”&#xff0c;可能是你下一步需要建立的重要工具哦&#xff01;今天&#xff0c;就让我们一起来看一下如何进行知识库的建设和维护。 首先&#xff0c;让我们理解一下知识库的定义。知识库就像是一…

探索Python数据结构与算法:解锁编程的无限可能

文章目录 一、引言1.1 数据结构与算法对于编程的重要性1.2 Python作为实现数据结构与算法的强大工具 二、列表和元组2.1 列表&#xff1a;创建列表、索引、切片和常用操作2.2 元组&#xff1a;不可变序列的特性和使用场景 三、字符串操作和正则表达式3.1 字符串的常见操作和方法…

第36期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

c语言-库函数strstr()、strtok()、strerror()介绍

文章目录 前言一、库函数strstr()1.1 strstr()介绍1.2 strstr()模拟实现 二、库函数strtok()2.1 strtok()介绍 三、库函数strerror()3.1 strerror()介绍 总结 前言 本篇文章介绍c语言库函数strstr()、strtok()、strerror()的使用。 一、库函数strstr() 1.1 strstr()介绍 str…

Linux/Networked

Enumeration nmap 网站更新之后有了一个引导模式&#xff0c;更利于学习了&#xff0c;之前看ippsec的视频&#xff0c;要不总是没有思路&#xff0c;现在出现的问题多了提示也更多了&#xff0c;还没有使用&#xff0c;一会用用再说 首先&#xff0c;第一个问题是“目标上正…

RocketMQ源码阅读-Producer消息发送

RocketMQ源码阅读-Producer消息发送 1. 从单元测试入手2. 启动过程3. 同步消息发送过程4. 异步消息发送过程5. 小结 Producer是消息的生产者。 Producer和Consummer对Rocket来说都是Client&#xff0c;Server是Broker。 客户端在源码中是一个单独的Model&#xff0c;目录为rock…

WordPress后台仪表盘自定义添加删除概览项目插件Glance That

成功搭建WordPress站点&#xff0c;登录后台后可以在“仪表盘 – 概览”中看到包括多少篇文章、多少个页面、多少条评论和当前WordPress版本号及所使用的主题。具体如下图所示&#xff1a; 但是如果我们的WordPress站点还有自定义文章类型&#xff0c;也想在概览中显示出来应该…

《计算机视觉处理设计开发工程师》

计算机视觉&#xff08;Computer Vision&#xff09;是一门研究如何让计算机能够理解和分析数字图像或视频的学科。简单来说&#xff0c;计算机视觉的目标是让计算机能够像人类一样对视觉信息进行处理和理解。为实现这个目标&#xff0c;计算机视觉结合了图像处理、机器学习、模…

我的年终总结2023

As a DBA 从2023年初开始&#xff0c;我就给自己定下了23年的主要任务——学习PostgreSQL数据库。虽然没有定下细致的计划&#xff0c;但总体的目标是把PG的一些基础知识学完。后来发现我想简单了&#xff0c;学习PG的成本比我想象的多的多&#xff0c;导致23年这个目标没有完…

【CSP】2023年12月真题练习(更新到202312-2)

试题编号&#xff1a;202312-1试题名称&#xff1a;仓库规划时间限制&#xff1a;1.0s内存限制&#xff1a;512.0MB问题描述&#xff1a; 问题描述 西西艾弗岛上共有 n 个仓库&#xff0c;依次编号为 1⋯n。每个仓库均有一个 m 维向量的位置编码&#xff0c;用来表示仓库间的物…

汽车生产污废水处理需要哪些工艺设备

对于汽车生产过程中产生的污废水处理&#xff0c;需要运用一系列的工艺设备来实现有效的清洁和回收利用。下面让我们一起来探索一下吧&#xff01; 首先&#xff0c;汽车生产工艺设备中最常见的是物理处理设备。物理处理包括沉淀、过滤和吸附等过程。其中&#xff0c;沉淀操作可…

Angular系列教程之观察者模式和RxJS

文章目录 引言RxJS简介RxJS中的设计模式观察者模式迭代器模式 示例代码RxJS 在 Angular 中的应用总结 引言 在Angular开发中&#xff0c;我们经常需要处理异步操作&#xff0c;例如从后端获取数据或与用户的交互。为了更好地管理这些异步操作&#xff0c;Angular中引入了RxJS&…

Java、C#、Python间的Battle

一、编译原理和开发效率 编译速度&#xff1a; C# &#xff08;约大于等于&#xff09; JAVA > Python python的编译原理 前提&#xff1a;python 3.6 python不会直接编译源码 而是把源码直接扔给解释器&#xff0c;这种方式 使得python非常灵活&#xff0c;让它的开发效…

从零开始:生产环境如何部署 Bytebase

Bytebase 是面向研发和 DBA 的数据库 DevOps 和 CI/CD 协同平台。目前 Bytebase 在全球类似开源项目中 GitHub Star 数排名第一且增长最快。 Bytebase 的架构 Bytebase 是一个单体架构 (monolith)&#xff0c;前端是 Vue3 TypeScript&#xff0c;后端是 Go。前端利用 Go 1.6 …

好用的内外网快速传输大文件方法

在信息化时代&#xff0c;数据已经成为各行各业的关键资产&#xff0c;数据的传输和交换方式直接影响着数据价值的体现。在众多场景下&#xff0c;我们需要在不同的网络环境中进行文件传输&#xff0c;如同一个局域网内或者互联网上。这时涉及到内外网的概念。 内外网指的是在不…

UE5 nDisplay群集事件的发送和接收

注意&#xff1a; 1.只能在投屏模式下生效 2.需要监听的机器都要执行“1.打开监听”

创意无限!亲测可用的免费Photoshop素材网站大揭秘!

高质量的PS材料可以保证设计师设计作品的质量&#xff0c;但很多人不知道在哪里找到一些免费的材料&#xff0c;尤其是对初学者来说。那么&#xff0c;有没有质量好、免费的PS材料网站呢&#xff1f;别担心&#xff0c;现在就告诉你。 即时设计 被很多人视为免费的PS素材网站…