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

Android JNI代码语法解释

文章目录

  • JNI中的JNIEXPORT、JNIIMPORT和JNICALL
  • JVM如何查找native方法
    • ①按照JNI规范的命名规则
    • ②调用JNI提供的RegsterNatives函数,将本地函数注册到JVM中
    • 示例代码
  • JNI数据类型
  • JNI字符串的处理
    • ①获取字符串
    • ②释放字符串
    • ③创建字符串
    • ④其他字符串处理API

JNI中的JNIEXPORT、JNIIMPORT和JNICALL

两个关键字的定义都可以在jni_md.h下找到

均用于定义与平台相关的宏

用于标识函数用途

  • JNIEXPORT:(实则为C++规则)放置在函数、变量或对象的声明前面,指示编译器将其导出为动态链接库的一部分。这使得其他程序可以通过在运行时加载动态链接库并使用导出的函数、变量或对象
  • JNIIMPORT:(实则为C++规则)放置在函数、变量或对象的声明前面,指示编译器将其标记为从动态链接库中导入的符号
  • JNICALL:(实则为C++规则)一种标准的函数调用约定,也被称为 “标准调用”;具有以下性质:
    函数的参数按照从右到左的顺序依次入栈。这意味着最右边的参数首先被压入栈中。
    调用方清理栈上的参数。这意味着在函数调用结束后,由调用方负责从栈上移除函数的参数。
    函数的返回值通常存储在 EAX 寄存器中
//Windows下的定义
#define JNIEXPORT __declspec(dllexport)
#define JNIIMPORT __declspec(dllimport)
#define JNICALL __stacall//Linux下的定义(实际是空定义)
#define JNIEXPORT
#define JNIIMPORT
#define JNICALL

JVM如何查找native方法

①按照JNI规范的命名规则

即根据JNI所约定的命名规则来指定函数的命名,具体规则如下:Java_类全路径_方法名

JNIEXPORT jstring JNICALL Java_com_kqli_jni_JniTest_getStringFromC(JNIEnv *env, jclass jclass);
JNIEXPORT jstring JNICALL Jave_com_test_jni_HelloWord_func(JNIEnv* env, jclass class, jstring str);
  • 第一个jstring为返回值(string类型)
  • 函数名中com_kqli_jni_JniTest_getStringFromC,代表Java类com_kqli_jni_JniTest,getStringFromC代表具体的函数名称
    JNIEnv,指向JVM函数表的指针
  • jclass,调用Java中native方法的实例对象

②调用JNI提供的RegsterNatives函数,将本地函数注册到JVM中

//函数原型
jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods);
  • clazz:声明native方法的类
  • methods:JNINativeMethod结构的数组
typedef struct {char *name;	//java方法名称char *signature;//java方法签名void *fnPtr;//c/c++的函数指针
} JNINativeMethod;
  • nMethods:指定methods数组中的本地方法数,通常写法为
nMethods = sizeof(methods) / sizeof(JNINativeMethod);

示例代码

java

package com.test.jni;public class A{static{System.loadLibrary("A");	}public static native int a(String str);public static native boolean b();public static native int c(Object obj);public static void main(String[] args){......}
}

native

jint a(JNIEnv *env ,jclass class, jstring str){....
}jboolean b(JNIEnv *env ,jclass class){....
}jint c(JNIEnv *env ,jclass class, jobject obj){....
}static JNINativeMethod method_table[] = 
{{"a", "(Ljava/lang/String;)I", (void *)a},{"b", "()Z", (void *)b},{"c", "(Ljava/lang/Object;)I", (void *)c},
};jint JNI_OnLoad(JavaVM* vm, void* reserved)
{......jclass clz = env ->FindClass(JNIREG_CLASS);env ->RegisterNatives(clz, method_table, sizeof(method_table) / sizeof(JNINativeMethod));......
}

JNI数据类型

在这里插入图片描述

类: 例如String的签名为Ljava/lang/String; 注意: 包名和类名用/隔开, 结尾有一个;
数组:用[表示数组签名, 例如int[]的签名为[I

JNI字符串的处理

①获取字符串

JNI通过jstring来处理字符串数据,但是jstring是指向JVM内部的字符串,和C风格的字符串类型char * 不同,因此必须使用合适的JNI函数来访问JVM内部的字符串。
因为Java默认使用unicode编码,而C/C++默认使用UTF编码,所以要注意进行编码转换。

const char* GetStringUTFChars(jstring str, jbbolean *isCopy);
  • str为需要获取的字符串
  • isCopy取值JNI_TRUE和JNI_FALSE,一般填NULL即可
  • JNI_TRUE:返回JVM内部源字符串的拷贝,并为新产生的字符串分配内存空间
  • JNI_FALSE:返回JVM内部源字符串的指针,并可以指针修改源字符串的内容

②释放字符串

通过GetStringUTFChars获取到字符串并返回的为源字符串拷贝后,在使用完毕要记得释放内存。

void ReleaseStringUTFChars(jstring str, const char* utf);
  • str为需要释放的字符串指针
  • utf为字节编码

③创建字符串

jstring NewStringUTF(const char * bytes);
  • bytes为C/C++的字符串数据源

④其他字符串处理API

  • GetStringChars、ReleaseStringChars:用于获取/释放Unicode格式的字符串
  • GetStringUTFLength、GetStringLength:用于获取UTF-8/Unicode格式的字符串长度
  • GetStringCritical、ReleaseStringCritical:用于直接返回/释放源字符串的指针,获取这个指针会导致暂停GC线程,如果GC线程暂停时又被其他线程触发GC的话,会出现系统死锁的阻塞调用
  • GetStringUTFRegion、GetStringRegion:用于获取UTF-8/Unicode格式字符指定范围内的内容,并会将源字符串复制到一个预先分配的缓冲区内

相关文章:

Android JNI代码语法解释

文章目录 JNI中的JNIEXPORT、JNIIMPORT和JNICALLJVM如何查找native方法①按照JNI规范的命名规则②调用JNI提供的RegsterNatives函数,将本地函数注册到JVM中示例代码 JNI数据类型JNI字符串的处理①获取字符串②释放字符串③创建字符串④其他字符串处理API JNI中的JNI…...

小程序和前台开发软件定制的相关信息|APP网站搭建

小程序和前台开发软件定制的相关信息 在如今数字化时代,软件、小程序和前台开发软件定制已经成为了企业必备的工具之一。那么,这些工具到底有什么作用呢?接下来,我将为大家详细介绍。 首先,让我们来了解一下软件。软件…...

JVM监控及诊断工具-GUI篇

文章目录 JVM监控及诊断工具-GUI篇工具概述JConsoleVisual VM再谈内存泄漏Java中内存泄漏的8种情况Arthas(阿尔萨斯)康师傅使用阿尔萨斯的例子help指令 JVM监控及诊断工具-GUI篇 工具概述 使用上一章命令行工具或组合能获取目标Java应用性能相关的基础…...

【C++STL基础入门】list基本使用

文章目录 前言一、list简介1.1 list是什么1.2 list的头文件 二、list2.1 定义对象2.2 list构造函数2.3 list的属性函数 总结 前言 STL(Standard Template Library)是C标准库的一个重要组成部分,提供了一套丰富的数据结构和算法,可…...

WSL+vscode配置miniob环境

1.配置WSL Windows Subsystem for Linux入门:安装配置图形界面中文环境vscode wu-kan 2.获取源码 找个位置Git Bash然后拉取代码 git clone https://github.com/oceanbase/miniob.git 3.安装相关依赖 https://gitee.com/liangcha-xyy/source/blob/master/how…...

Flutter SliverAppBar 吸顶效果

吸顶是常见的布局,主要使用的是CustomScrollView 和SliverApp组件实现的 页面布局 overrideWidget build(BuildContext context) {return CustomScrollView(controller: controller.scrollController!,physics: const BouncingScrollPhysics(),slivers: [SliverApp…...

Java Spring Boot 自动装配:简化配置和提高开发效率

Spring Boot 自动装配是 Spring Boot 提供的一种特性,它可以根据应用程序的依赖关系和配置信息,自动配置应用程序的各种组件和功能。这样,开发者可以将更多的精力放在业务逻辑的实现上,而不需要手动配置和管理各种组件。 1. 自动…...

对象转换之modelmapper

1. 官网地址:http://modelmapper.org 源码地址:GitHub - modelmapper/modelmapper: Intelligent object mapping 2.实现原理: 主要是基于匹配策略进行属性的转化,目前支持三种策略: 2.1 Standard(默认标准…...

Ant Design+react 路由跳转

今天我们来继续探讨react的路由跳转 首先,创建router文件夹中的index import { lazy } from "react"; import { Outlet,useRoutes } from react-router-dom; //引入页面,引用了路由懒加载 const One lazy(() > import(../pages/one)); c…...

提高爬虫效率的秘诀之一:合理配置库池数量

在提高爬虫效率的过程中,合理配置库池数量是一个重要的秘诀。通过增加或减少库池的数量,可以有效提升爬虫系统的效率和稳定性。本文将介绍如何合理配置库池数量,以及配置不同数量库池的优缺点,帮助您提高爬虫效率,顺利…...

初学者必看,前端 Debugger 调试学习

1.文章简介: 报错和Bug,是贯穿程序员整个编程生涯中,无法回避的问题。而调试,就是帮助程序员定位问题、解决问题的重要手段,因此调试是每个程序员必备技能。 调试本身可分为两个过程: 定位问题 和 解决问题&#xff0…...

Dubbo—Admin 整体架构与安装步骤

​回顾 Dubbo 服务治理体系的总体架构,Admin 是服务治理控制面中的一个核心组件,负责微服务集群的服务治理、可视化展示等。 Admin 部署架构 总体上来说,Admin 部署架构分为以下几个部分: Admin 主进程,包括服务发现…...

C++11打断线程的几种方式

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pthread_cancel1.代码演示2.两个重要方法1.pthread_setcancelstate2.pthread_setcanceltype 3.资源回收 二、Boost1.看代码2.资源泄露2.资源回收 总结 前言…...

如何提升网站排名和用户体验:优化网站速度

网站的排名和用户满意度直接受到站点内容的加载速度影响深远。通过精心的网站优化,您不仅可以提高排名,还可以提供更出色的用户体验,尽管用户可能不会察觉到您的网站加载得更快,但这是一个非常有意义的改进。在这篇文章中&#xf…...

【Redis】Hash 哈希内部编码方式

Hash 哈希内部编码方式 哈希的内部编码有两种: ziplist(压缩列表):当哈希类型元素个数⼩于hash-max-ziplist-entries配置(默认512个)、同时所有值都⼩于hash-max-ziplist-value配置(默认64字节…...

JUC第二十八讲:JUC工具类: Semaphore详解

JUC工具类: Semaphore详解 本文是JUC第二十八讲,JUC工具类: Semaphore详解。Semaphore底层是基于AbstractQueuedSynchronizer来实现的。Semaphore称为计数信号量,它允许n个任务同时访问某个资源,可以将信号量看做是在向外分发使用资源的许可证…...

vue3组合式API实现父组件触发子组件中的方法 | vue3中ref的用法 | defineExpose的使用场景

vue3组合式API实现父组件触发子组件中的方法 | vue3中ref的用法 | defineExpose的使用场景 目录 vue3组合式API实现父组件触发子组件中的方法 | vue3中ref的用法 | defineExpose的使用场景一、问题背景二、解决方法三、示例 一、问题背景 代码环境:vue3 &#xff0…...

【Qt之QTableWidget和QTreeWidget】树悬停、选择样式及表格表头和首行间隔线

QTableWidget设置表头与首行间隔线 win10 实例化QTableWidget后,表格表头和首行中间无间隔线,以下是通过样式表进行设置: // 设置横向表格头的间隔线,可设置四个方向的间隔线,不需要间隔线的可以设置为0px// border-left:0px sol…...

使用余弦算法计算向量相似性

import pandas as pd import numpy as np import openaifrom openai.embeddings_utils import get_embedding, cosine_similarityopenai.api_key sk-???? embedding_model "text-embedding-ada-002" embedding_encoding "cl100k_base" # this the …...

存档&改造【06】Apex-Fancy-Tree-Select花式树的使用误删页数据还原(根据时间节点导出导入)

之前一直想实现厂区-区域-产线之间的级联选取,于是导入插件Apex-Fancy-Tree-Select花式树 存档&改造【03】Apex-Fancy-Tree-Select花式树的导入-CSDN博客 现在则是在Oracle Apex中的应用 花式书级联列表展示厂区-区域-产线 想要实现的效果 由厂区>…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

零基础设计模式——行为型模式 - 责任链模式

第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

浅谈不同二分算法的查找情况

二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况&#xf…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...

Go语言多线程问题

打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...