《Android框架揭秘》读书笔记--在Java中调用C库函数

article/2025/11/10 11:22:45

简介

以下试验在Ubuntu16.04 x86,jdk安装:sudo apt-get install openjdk-9-jdk-headless,原书介绍的是在win系统实现。

  • 步骤
    • 第一步:编写Java代码
    • 第二步:编译Java代码
    • 第三步:生成C语言头文件
    • 第四步:编写C代码
    • 第五步:生成C共享库
    • 第六步:运行Java程序
  • 第一步:编写Java代码
    • 创建HelloJNI.java
      class HelloJNI
      {//本地方法声明native void printHello();native void printString(String str);//加载库 以下两种方法任意一个都可以static{System.loadLibrary("hellojni");} //库名(不带lib)//static{System.load("/home/qb/work/ndk/libhellojni.so");} //绝对路径 + *.so
      ​​public static void main(String args[]){HelloJNI myJNI = new HelloJNI();//调用本地方法(实际调用的是使用C语言编写的JNI本地函数)myJNI.printHello();myJNI.printString("Hello World from printString fun");​​​​}​​​ ​
      }​​​
  • 第二步:编译Java代码
    • javac HelloJNI.java
      • 编译HelloJNI.java源文件
      • 生成HelloJNI.class类文件
  • 第三步:生成C语言头文件
    若想创建本地方法的映射C函数,必须先生成函数原型,函数原型存在于C/C++头文件中,Java提供了javah工具,它位于<JDK_HOME>\bin目录下,用来生成包含函数原型的C/C++头文件,其使用方法如下。
        javah <包含以native关键字声明的方法的Java类名称>
    运行javah命令,会在当前目录下生成与Java类名(即javah命令的参数)相同名称的C语言头文件。在生成的C头文件中,定义了与Java本地方法相链接的C函数原型。​​
    • javah HelloJNI
      1、该头文件由javah命令生成,为了保证JNI正常运行,请不要直接修改本文件的内容
      2、各函数原型对应的Java代码中的本地方法,注释中标明了三个元素:类名、本地方法名、本地方法签名。只要生成了这样的函数原型,Java虚拟机就能把本地库函数与Java本地方法正常地链接在一起。
      3、函数原型必须包含JNI关键字​​:JNIEXPORT、JNICALL,都是宏定义,定义在<JDK_HOME>/include/win32/jni_md.h​
      4、Java本地类型(jbyte、jint、jchar...)被定义在以下头文件中
      <JDK_HOME>/include/jni.h
      <JDK_HOME>/include/platform/jni_md.h​​​
    • 生成HelloJNI.h(以下代码是系统自动生成,且不要去做修改)
      /* DO NOT EDIT THIS FILE - it is machine generated */
      #include <jni.h>
      /* Header for class HelloJNI */
      #ifndef _Included_HelloJNI
      #define _Included_HelloJNI
      #ifdef __cplusplus
      extern "C" {
      #endif
      /** Class:     HelloJNI* Method:    printHello* Signature: ()V*/
      JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *, jobject);
      /** Class:     HelloJNI* Method:    printString* Signature: (Ljava/lang/String;)V*/
      JNIEXPORT void JNICALL Java_HelloJNI_printString(JNIEnv *, jobject, jstring);
      #ifdef __cplusplus
      }
      #endif
      #endif
      ​
    • JNI支持的函数命名形式:Java_类名_本地方法名
  • 第四步:编写C/C++代码
    • 创建hellojni.c
      #include <jni.h>
      #include <stdio.h>
      //添加名称为env与obj的两个参数
      JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *env, jobject obj)
      {printf("Hello World!\n");return;
      }
      JNIEXPORT void JNICALL Java_HelloJNI_printString(JNIEnv *env, jobject obj, jstring string)
      {//将Java String转换为C字符串const char *str = (*env)->GetStringUTFChars(env, string, 0);printf("%s!\n", str);return;
      }
  • 第五步:生成C共享库
    • gcc -fpic -shared hellojni.c -o libhellojni.so -I/usr/lib/jvm/java-9-openjdk-amd64/include -I/usr/lib/jvm/java-9-openjdk-amd64/include/linux
      1、可能遇到报错:
      fatal error: jni.h: No such file or directory
      fatal error: jni_md.h: No such file or directory
      找不到jni.h和jni_md.h,只要加上​​​-I + jni.h路径,因我的linux安装的是sudo apt-get install openjdk-9-jdk-headless,故jni.h在/usr/lib/jvm/java-9-openjdk-amd64/include;
      ​jni_md.h在/usr/lib/jvm/java-9-openjdk-amd64/include
  • 第六步:运行Java程序
    • java HelloJNI
      ​1、可能遇到报错:
      Exception in thread "main" java.lang.UnsatisfiedLinkError: no hellojni in java.library.path
      at java.lang.ClassLoader.loadLibrary(java.base@9-internal/ClassLoader.java:2274)
      at java.lang.Runtime.loadLibrary0(java.base@9-internal/Runtime.java:874)
      at java.lang.System.loadLibrary(java.base@9-internal/System.java:1807)
      at HelloJNI.<clinit>(HelloJNI.java:8)
      ​解决方法:export LD_LIBRARY_PATH=./
    • 运行结果

http://chatgpt.dhexx.cn/article/Ok8GjarT.shtml

相关文章

Android 框架揭秘 --读书笔记

Android 框架揭秘 Insied the Android Framework 转载于:https://www.cnblogs.com/drduan/p/4788554.html

android框架揭秘!Android开发者跳槽指南一线互联网公司面经总结

前言概要&#xff1a; 1&#xff0c;进大公司还是小公司&#xff0c;真的有的选&#xff1f; 2&#xff0c;校招的潜规则 3&#xff0c;校招想进大厂怎么办 4&#xff0c;社招的潜规则 5&#xff0c;社招想进大厂怎么办&#xff1f; 面试部门 岗位&#xff1a;商业化 - 高级 …

《Android框架揭秘》——导读

本节书摘来自异步社区《Android框架揭秘》一书中的目录&#xff0c;作者 金泰延 , 宋亨周 , 朴知勋 , 李白 , 林起永&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看 目 录 第1章 Android Framework概要 1.1 Android源代码组成1.2 通过启动过程分析Android…

Android框架揭秘读书笔记

Android启动过程 1.linux内核&#xff0c;加载linux内核 2 init 进程对各种设备进行初始化&#xff0c; 执行Daemon进程&#xff0c;管理USB、ADB链接管理器、Debugger系统、rild管理无线通信链接 Content Manager进程&#xff0c;提供运行Android各种系统服务信息 Media …

android框架揭秘!连续四年百度Android岗必问面试题!实战篇

前言 今天想停下代码&#xff0c;写点脑袋里不断浮现出来的一些看法。 也就是最近在微博和知乎上老看到“互联网寒冬”的说法。要么是看到啥公司薪水无法如期发放了&#xff0c;要么是看到别人说什么“裁员了&#xff0c;没有交接&#xff0c;签字然后电脑还了就走人&#xf…

字节大佬封神之作《Android Framework高级开发笔记》,完整版开放下载

在现阶段的Android开发工作中&#xff0c;无论是底层&#xff0c;还是应用层&#xff0c;Framework都至关重要。Framework的火热程度&#xff0c;相信我也不必再赘述。 为帮助大家深度学习Framework背景及它的巨大作用&#xff0c;这里分享一份《Android Framework高级开发笔记…

ANDROID框架揭秘

本书通过对Android系统源代码的分析&#xff0c;主要介绍Android框架的初始化过程及 主要组件的工作原理。作者直接分析和整理了Android框架的主要源代码&#xff0c;并详细讲 解了理解框架工作原理所需的各种基础知识和构成实际Android平台骨干的服务框架。 其中的主要内容包括…

用Java写linux命令行cd,java执行linux命令cd

java执行linux命令cd [2021-01-31 01:51:23] 简介: php去除nbsp的方法&#xff1a;首先创建一个PHP代码示例文件&#xff1b;然后通过“preg_replace("/(\s|\&nbsp\;| |\xc2\xa0)/", " ", strip_tags($val));”方法去除所有nbsp即可。推荐&#xff1…

Linux 常用命令与教程

http://c.biancheng.net/view/705.html C语言编程网的教程很好 还有菜鸟教程的 还有这个 https://mp.weixin.qq.com/s/7bSwKiPmtJbs7FtRWZZqpA 讲的也不错 https://baike.baidu.com/item/PS/8850709 百度百科 搜索一个linux命令 会出来这个 〇、序言&#xff1a;命令基本格式…

最强的linux命令总结.pdf

白月光-焰灵姬 来源&#xff1a;掘金- Lion https://juejin.cn/post/6938385978004340744 | 编辑&#xff1a;五角钱的程序员 前言 Linux 的学习对于一个程序员的重要性是不言而喻的。前端开发相比后端开发&#xff0c;接触 Linux机会相对较少&#xff0c;因此往往容易忽视它。…

linux命令 视频教程,常用的linux命令视频教程

常用的linux命令视频教程 [2021-02-19 11:27:41] 简介: php去除nbsp的方法&#xff1a;首先创建一个PHP代码示例文件&#xff1b;然后通过“preg_replace("/(\s|\&nbsp\;| |\xc2\xa0)/", " ", strip_tags($val));”方法去除所有nbsp即可。推荐&#…

ps 命令详解

From&#xff1a;http://blog.chinaunix.net/uid-25681671-id-3201927.html 进程和作业管理命令&#xff1a;http://man.linuxde.net/sub/进程和作业管理 Linux 关于 进程/线程 的命令 kill 和 pgrep 和 pidof 和 awk 和 pkill 和 killall&#xff1a;https://blog.csdn.net/fr…

Linux命令详解词典高频命令(三)

ln(link) 功能说明&#xff1a;链接文件或目录。 语法&#xff1a;$ ln [参数] [被链接文件] [链接目录] 包名称&#xff1a;coreutils 相关命令&#xff1a;cp,lndir,symlinks 补充说明&#xff1a;ln命令用在链接文件或目录&#xff0c;如同时指定两个以上的文件或目录&…

Linux命令详解词典高频命令(1)

参考机械工业出版社&#xff0c;施威铭研究室著的《Linux命令详解词典》 列出了其中的一些高频命令供自己学习 alias 功能说明&#xff1a;设置命令的别名。 语 法&#xff1a;-$ alias [别名][命令] 包 名 称&#xff1a;bash 相关命令&#xff1a;unalias 命令说明&#xf…

linux命令 语法 pdf,Linux命令详解词典pdf

摘要 精选381个命令&#xff0c;详细列出1729个范例&#xff0c;提供3种查询索引&#xff0c;适合各种Linux发行版。 Linux命令详解词典 内容简介 本书精选了381个Linux命令&#xff0c;详细罗列1729个范例&#xff0c;并提供3种查询索引方式。本书详细列出Linux命令的参数、功…

linux命令详解词典pdf,[计算机]linux命令详解词典

[计算机]linux命令详解词典 (42页) 本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01; 22.9 积分 linux命令详解词典cat cdchmod chowncp cut名称&#xff1a;cat使用权限&#xff1a;所有使用者使用方式…

【基础篇】linux常用命令大全及命令说明

对于刚接触linux来说&#xff0c;命令是必不可少的。在linux中很多东西都是要用命令来控制&#xff0c;接下来就将我所了解到的常用命令列举一下&#xff0c;供大家参考&#xff1a; 一、基础命令 su root : 进入管理员用户 cd &#xff1a;切换到当前用户的主目录 cd 目录…

Linux命令详解词典高频命令(2)

grep 功能说明&#xff1a;查找文件里符合条件的字符串 语 法&#xff1a;# grep [参数] [查找范例] *[文件类型] 包 命 令&#xff1a;grep 相关命令&#xff1a;egrep,fgrep,rgrep 补充说明&#xff1a;命令用于査找内容包含指定范本样式的文件&#xff0c;如果发现某文件的…

100个linux常用命令,肝货,很实用

Linux命令是对Linux系统进行管理的命令。 对于Linux系统来说&#xff0c;无论是中央处理器、内存、磁盘驱动器、键盘、鼠标&#xff0c;还是用户等都是文件&#xff0c;Linux系统管理的命令是它正常运行的核心。 线上查询及帮助命令(2个) man&#xff1a;查看命令帮助&#xff…

windows下强制删除文件

windows下强制删除文件 新建记事本在记事本中添加代码重命名为del.bat删除文件 新建记事本 在记事本中添加代码 DEL /F /A /Q \\?\%1 RD /S /Q \\?\%1重命名为del.bat 删除文件