[Android]查找java类中声明为native方法的具体实现方法
在android代码中,经常可以看到native方法,需要查看其对应的C++方法,这些方法是一一对应的,对应关系是在jni注册里关联起来的。
比较直观的是这样的例子,
Parcel.java
//Java层的方法里调用了native方法nativeWriteInt(mNativePtr, val)
public final void writeInt(int val) {
nativeWriteInt(mNativePtr, val);
}
//Java层中声明了native方法
private static native void nativeWriteInt(long nativePtr, int val);
private static native void nativeWriteLong(long nativePtr, long val);
以 nativeWriteInt方法为例,进而会调用到frameworks/base/core/jni/android_os_Parcel.cpp中的android_os_Parcel_writeInt方法。
搜nativeWriteInt,可以看到{"nativeWriteInt", "!(JI)V", (void*)android_os_Parcel_writeInt}
以{"nativeWriteInt", "!(JI)V", (void*)android_os_Parcel_writeInt}为例,
nativeWriteInt是Java层Parcel.java中声明的函数名称,而android_os_Parcel_writeInt是JNI层android_os_Parcel.cpp中对应的函数。
"!(JI)V"是函数签名,对函数的参数和返回值进行标记,采用了函数签名,即便是重载了的同名函数,都可以通过函数签名来进行区分。
通过这样的映射处理,Java层就和Native层关联起来了。
通过RegisterMethodsOrDie(env, kParcelPathName, gParcelMethods, NELEM(gParcelMethods))调用最终来实现了JNI方法的关联。android.os.Parcel类中的nativeWriteInt方法对应着android_os_Parcel.cpp中的static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val)方法。
static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val) {
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->writeInt32(val);
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
android_os_Parcel_writeInt方法中又调用了C++层的Parcel类,进而通过JNI实现了Java层对C++层方法的调用。
gParcelMethods是JNINativeMethod类型的数组,存储了Java层函数和native函数的映射关系。
还有一种不太直观的描述,
比如libcore/ojluni/src/main/java/java/net/NetworkInterface.java
里的
393 private static NetworkInterface[] getAll() throws SocketException {
394 // Group Ifaddrs by interface name.
395 Map<String, List<StructIfaddrs>> inetMap = new HashMap<>();
396
397 StructIfaddrs[] ifaddrs;
398 try {
399 ifaddrs = Libcore.os.getifaddrs();
400 } catch (ErrnoException e) {
401 throw e.rethrowAsSocketException();
402 }
这里查找getifaddrs方法的实现,找到Libcore.java
继续找到libcore/luni/src/main/java/libcore/io/Linux.java
public native StructIfaddrs[] getifaddrs() throws ErrnoException;
是个native方法,具体的实现是哪里呢,
可以搜到
libcore/luni/src/main/native/libcore_io_Linux.cpp
NATIVE_METHOD(Linux, getifaddrs, "()[Landroid/system/StructIfaddrs;"),
这个跟上面的不一样,看不出来对应的方法,
原来,NATIVE_METHOD是个宏,
在libnativehelper/include/nativehelper/JniConstants.h
里有
82#define NATIVE_METHOD(className, functionName, signature) \
83 { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName) }
这个宏里进行了字符串拼接,展开这个宏,
{ "getifaddrs", "()[Landroid/system/StructIfaddrs;", reinterpret_cast<void*>(Linux_getifaddrs) }
所以,是Linux_getifaddrs方法
1517static jobjectArray Linux_getifaddrs(JNIEnv* env, jobject) {
1518 static jmethodID ctor = env->GetMethodID(JniConstants::structIfaddrs, "<init>",
1519 "(Ljava/lang/String;ILjava/net/InetAddress;Ljava/net/InetAddress;Ljava/net/InetAddress;[B)V");
1520 if (ctor == NULL) {
1521 return NULL;
相关文章:
[Android]查找java类中声明为native方法的具体实现方法
在android代码中,经常可以看到native方法,需要查看其对应的C方法,这些方法是一一对应的,对应关系是在jni注册里关联起来的。 比较直观的是这样的例子, Parcel.java //Java层的方法里调用了native方法nativeWriteInt…...

Exploring Defeasible Reasoning in Large Language Models: A Chain-of-Thought A
文章目录 题目摘要简介准备工作数据集生成方法实验结论 题目 探索大型语言模型中的可废止推理:思路链 论文地址:http://collegepublications.co.uk/downloads/LNGAI00004.pdf#page136 摘要 许多大型语言模型 (LLM) 经过大量高质量数据语料库的训练&…...
uniapp在app模式下组件传值
在 UniApp 编译成 App 后,传递参数可以通过多种方式实现,常见的方式有以下几种: 1. 通过 URL 参数传递(适用于 WebView) 如果你的 App 页面通过 WebView 渲染,可以像在 Web 端一样通过 URL 传递参数。例如…...
Docker解决暴露2375端口引发的安全漏洞
docker的暴露api端口2375,没有任何安全防护,我们通过linux系统防火墙(iptables)来进行ip访问限制 # 查看iptables所有规则 iptables -L -nv # 只允许某个ip访问2375端口 iptables -I INPUT -s 127.0.0.1 -p tcp --dport 2375 -j A…...

HTML5+CSS前端开发【保姆级教学】+新闻文章初体验
Hello,各位编程猿们!上一篇文章介绍了前端以及软件的安装,这一篇我们要继续讲解页面更多知识点,教大家做一篇新闻题材的文章 新闻文章 当我们点开浏览器经常看到各种各样的文章,今天我们就来看看大家最喜欢关注的体育…...

『VUE』26. props实现子组件传递数据给父组件(详细图文注释)
目录 本节内容示例代码总结 欢迎关注 『VUE』 专栏,持续更新中 欢迎关注 『VUE』 专栏,持续更新中 本节内容 父组件传子组件–props 子组件传父组件–自定义事件 本节讲子组件传父组件–通过props里的方法传递,就是父亲写了一个函数,给子组件调用,然后…...

RHCE-DNS域名解析服务器
一、DNS简介 DNS ( Domain Name System )是互联网上的一项服务,它作为将域名和 IP 地址相互映射的一个分布式 数据库,能够使人更方便的访问互联网。 DNS 系统使用的是网络的查询,那么自然需要有监听的 port 。 DNS 使…...

移民统计年鉴(1996-2021年)
年鉴中包含了以下几个方面的数据: 移民数量:记录了每年全球移民的总数,以及不同国家和地区的移民流入和流出情况。 移民类型:区分了经济移民、难民、家庭团聚等不同类型的移民。 移民原因:分析了推动移民的各种因素&…...

MFC1(note)
引言 在学习SDK后我们发现,写消息好麻烦,处理消息更麻烦 处理消息效率低发送消息效率低 所以把SDK中这些消息全部封装好 MFC封装了windows 的大部分API 这里说一下QT架构跨平台 MFC用得如何取决于你SDK的水平 创建 如果打开没有MFC 一般勾选以下…...
1.1 关于游戏编程
1.1.1、游戏中客户端和服务器的交互 游戏通常采用客户端-服务器模式。在这种模式下,服务器负责处理游戏的核心逻辑、数据存储和玩家间的交互,而客户端则负责呈现游戏画面、接收玩家输入并与服务器通信。 客户端和服务器的作用和功能 客户端&a…...

光流法与直接法在SLAM中的应用
本文总结视觉SLAM中常用的光流法与直接法 1、Lucas-Kanade光流法 相机所拍摄到的图像随相机视角的变化而变化,这种变化也可以理解为图像中像素的反向移动。“光流”(Optical Flow)是指通过分析连续图像帧来估计场景中像素或特征点的运动的技…...

C++模板特化实战:在使用开源库boost::geometry::index::rtree时,用特化来让其支持自己的数据类型
用自己定义的数据结构作为rtree的key。 // rTree的key struct OverlapKey {using BDPoint boost::geometry::model::point<double, 3, boost::geometry::cs::cartesian>; //双精度的点using MyRTree boost::geometry::index::rtree<OverlapKey, boost::geometry::in…...

让空间计算触手可及,VR手套何以点石成金?
引言 如何让一位母亲与她去世的小女儿“重逢”?韩国MBC电视台《I Met You》节目实现了一个“不可能”心愿。 在空旷的绿幕中,母亲Jang Ji-sung透过VR头显,看到了三年前因白血病去世的女儿Nayeon。当她伸出双手,居然能摸到女儿的…...

穿越数据迷宫:C++哈希表的奇幻旅程
文章目录 前言📔一、unordered系列关联式容器📕1.1 unordered 容器概述📕1.2 哈希表在 unordered 容器中的实现原理📕1.3 unordered 容器的特点 📔二、unordered_set 和 unordered_map 的基本操作📕2.1 un…...

SMT32 智能环境监测系统 嵌入式初学者课堂小组作业
一、应用知识 1,开发语言:C语言 2,开发工具:Keil uVision5、Setup_JLinkARM_V415e 3,开发平台:XCOM V2.0 4,开发知识:温湿度传感DHT11、STM32F4xx中文参考手册 5,文…...

20241114给荣品PRO-RK3566开发板刷Rockchip原厂的Android13下适配RJ45以太网卡
20241114给荣品PRO-RK3566开发板刷Rockchip原厂的Android13下适配RJ45以太网卡 2024/11/14 15:44 缘起:使用EVB2的方案,RJ45加进去怎么也不通。 实在没有办法,只能将荣品的SDK:rk-android13-20240713.tgz 解压缩,编译之…...
JVM这个工具的使用方法
JVM(Java虚拟机)是Java程序运行的基础环境,它提供了内存管理、线程管理和性能监控等功能。吃透JVM诊断方法,可以帮助开发者更有效地解决Java应用在运行时遇到的问题。以下是一些常见的JVM诊断方法: 使用JConsole: JCon…...
创建型设计模式与面向接口编程
创建型设计模式(Creational Patterns)的主要目的之一就是帮助实现面向接口编程,避免直接创建实现类的实例。通过这些模式,可以将对象的创建过程封装起来,使得客户端代码不需要知道具体的实现类,从而提高代码…...

算法每日双题精讲——滑动窗口(长度最小的子数组,无重复字符的最长子串)
🌟快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。 🌟 别再犹豫了!快来订阅我们的算法每日双题精讲专栏,一起踏上算法学习的精彩之旅吧!💪…...

1.7 JS性能优化
从输入url到页面加载完成都做了些什么 输入 URL - 资源定位符 http://www.zhaowa.com - http 协议 域名解析 https://www.zhaowa.com > ip 1. 切HOST? > 浏览器缓存映射、系统、路由、运营商、根服务器 2. 实际的静态文件存放? 大流量 > 多个…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...