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,是贯穿程序员整个编程生涯中,无法回避的问题。而调试,就是帮助程序员定位问题、解决问题的重要手段,因此调试是每个程序员必备技能。 调试本身可分为两个过程: 定位问题 和 解决问题࿰…...

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

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

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

【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 ࿰…...

【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中的应用 花式书级联列表展示厂区-区域-产线 想要实现的效果 由厂区>…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...