mac上简单实现一个java调用C接口的JNI

目录

  • 安装JDK及配置环境变量
  • 写Java代码
  • 生成头文件
  • 实现本地方法
  • 编译本地代码
  • 运行 Java 程序
  • 总结步骤

安装JDK及配置环境变量

参考:MAC系统安装JDK1.8及环境变量配置

写Java代码

// 文件名:Calculator.java
public class Calculator {// 声明本地方法public native int add(int a, int b);// 加载动态链接库static {try {System.load("/Users/zhanghao/Downloads/java_excise/jni示例/libcalculator.so");//这里必须使用绝对路径} catch (UnsatisfiedLinkError e) {System.err.println("Failed to load library: " + e.getMessage());}}public static void main(String[] args) {System.out.println("Ready to add!");Calculator calculator = new Calculator();int result = calculator.add(5, 3);System.out.println("Result: " + result);}
}

在这段 Java 代码中,我们声明了一个本地方法 add,它将在后面的 C 代码中实现。
我们还使用 System.loadLibrary 方法加载动态链接库libcalculator.so,它也将由后面的.c和.h文件生成。
注意到"/Users/zhanghao/Downloads/java_excise/jni示例/libcalculator.so"这个路径,他也是当前文件Calculator.java所在的路径。

生成头文件

在终端中,切换到包含 Java 代码的目录,并运行以下命令:

javac -h . Calculator.java
//新版JDK不支持javah指令,只能用javac -h

这步将生成2个文件,第1个是名叫 Calculator.h 的头文件,它包含了我们需要在 C 代码中实现的本地方法的声明。第2个是叫Calculator.class文件,它是Java 编译后的字节码文件,用于最后通过Java指令执行。如下图:
在这里插入图片描述

其中,Calculator.h内容如下(第一行已经写明这是机器生成的文件,不需要改它):
在这里插入图片描述

实现本地方法

打开生成的头文件 Calculator.h看一下,并创建一个Calculator.c文件,在里面实现 Java_Calculator_add 方法。

// 文件名:Calculator.c
#include <stdio.h>
#include "Calculator.h"JNIEXPORT jint JNICALL Java_Calculator_add(JNIEnv *env, jobject obj, jint a, jint b) {printf("in C program!\n");return a + b;
}

在这个 C 文件中,我们先是加了打印,然后实现了头文件中声明的本地方法 Java_Calculator_add,它将两个整数相加并返回结果。

编译本地代码

在终端中,使用 GCC 编译器,运行以下命令来编译本地代码,并生成动态链接库:

gcc -c -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" Calculator.c
gcc -shared -o libcalculator.so Calculator.o

这将生成名为 libcalculator.so 的动态链接库文件,其中包含了我们的本地方法的实现。

解释一下这2条指令:
-c: 这个选项告诉编译器只进行编译,而不进行链接。这意味着它将产生一个目标文件而不是可执行文件。
-fPIC: 这个选项告诉编译器生成位置独立的代码(pasition independent code,这对于动态链接库(Shared Object)非常重要。
-I"xxx": 这个选项告诉编译器去 xxx 目录下查找头文件。在这个目录下,通常会有 jni.h , jni_md.h等 JNI 相关的头文件。
-shared表示生成一个共享库(动态库)文件。该条指令表示将 Calculator.o 这个目标文件编译并链接成一个名为 libcalculator.so 的共享库。

如果第一条指令失败,需要回头检查JDK的配置,通过echo $JAVA_HOME来查看Java的环境变量,如下图:
在这里插入图片描述

运行 Java 程序

在终端中,运行以下命令来执行 Java 程序:

java Calculator

输出结果是:
在这里插入图片描述

通过这个示例,我们可以了解到如何使用 JNI 来调用本地 C 代码,并将其集成到 Java 程序中。

总结步骤

共有下面几条指令:

//创建并撰写Calculator.java
javac -h . Calculator.java
//创建并撰写Calculator.c
gcc -c -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" Calculator.c
gcc -shared -o libcalculator.so Calculator.o
java Calculator

共有下面6个文件

$ls
Calculator.c		Calculator.h		Calculator.o
Calculator.class	Calculator.java		libcalculator.so

其中只有.java和.c文件需要手动写,其余都是自动生成的。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何禁止U盘拷贝文件|禁止U盘使用的软件有哪些

禁止U盘拷贝文件的方法有很多&#xff0c;比如使用注册表、组策略编辑器等&#xff0c;但这些方法都适合个人&#xff0c;不适合企业&#xff0c;因为企业需要对下属多台电脑进行远程管控&#xff0c;需要方便、省时、省力的方法。目前来说&#xff0c;最好的方法就是使用第三方…

嵌入式单片机笔试题

DC-DC 和 LDO两者有何区别&#xff1f; DC-DC转换器&#xff08;直流-直流转换器&#xff09;和LDO&#xff08;低压差线性稳压器&#xff09;都是用于电源管理的设备&#xff0c;但它们在原理和特性上有一些显著的区别&#xff1a; 原理&#xff1a; DC-DC转换器通过改变输…

WGCAT工单系统如何配置通知

WGCAT工单系统可以配置邮件通知 只要配置了邮件通知&#xff0c;那么一旦我们账号有新的工单需要处理&#xff0c;就会接受到邮件通知 除了邮件之外&#xff0c;还可以配置其他方式的通知&#xff0c;比如微信钉钉短信等方式&#xff0c;参考如下 https://www.wgstart.com/wgc…

2024年贵州特岗教师招聘报名流程,速速查收哦!

2024年贵州特岗教师招聘报名流程&#xff0c;速速查收哦&#xff01;

利用开源工具创建WEBGIS应用

在本文中&#xff0c;我们将大致说明利用开源工具如何与服务器交互以构建交互式或动态 Web GIS。 WebGIS 应用程序已成为展示地理数据的重要模式。我们现在拥有允许用户交互的机制&#xff0c;以便用户可以选择数据&#xff0c;甚至修改或添加新数据。 什么是WEBGIS? 通过网络…

博客说明 5/12~5/24【个人】

博客说明 5/12~5/24【个人】 前言版权博客说明 5/12~5/24【个人】对比最后 前言 2024-5-24 13:39:23 对我在2024年5月12日到5月24日发布的博客做一下简要的说明 以下内容源自《【个人】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作…

嵌入式单片机启动地址映射关系

一、内核只会从0地址启动 1.0地址第一个字是sp栈指针,第二个字是Reset_Handler入口,参考图1中启动代码中的中断向量表。具体使用流程参考图2(参考自野火) 图1 图2 2.0地址映射以后,软件上使用0地址访问的空间是映射到的器件的空间 3.0地址映射只会影响单个器件上的地址,…

轻量级 K8S 环境 安装minikube

文章目录 操作系统DockerDocker CE 镜像源站使用官方安装脚本自动安装 &#xff08;仅适用于公网环境&#xff09;安装校验Docker代理docker permission denied while trying to connect to the Docker daemon socket minikubekubectl工具minikube dashboard参考资料 操作系统 …

AI大模型探索之路-基础篇5:GLM-4解锁国产大模型的全能智慧与创新应用

目录 前言一、GLM4大模型总体概述二、GLM4和GPT4功能对比三、GLM4和GPT4性能对比1、基础能力&#xff08;英文&#xff09;2、指令跟随能力3、对齐能力4、长文本能力5、多模态-文生图 四、GLM-4 ALL Tools1、文生图2、代码解释器3、网页浏览4、Function Call5、多工具自动调用 …

23种设计模式(持续输出中)

一.设计模式的作用 设计模式是软件从业人员长期总结出来用于解决特定问题的通用性框架&#xff0c;它提高了代码的可维护性、可扩展性、可读性以及复用性。 二.设计模式 1.工厂模式 工厂模式提供了创建对象的接口&#xff0c;而无需制定创建对象的具体类&#xff0c;工厂类…

HarmonyOS之ArkUI布局设计常见细节

这里写目录标题 1. Button设置带有渐变色的背景图片无效1.1 问题分析1.2 成功案例 2. 路由跳转失败2.1 问题分析 1. Button设置带有渐变色的背景图片无效 1.1 问题分析 说明&#xff1a;设置颜色渐变需先设置backgroundColor为透明色。 Button($r(app.string.login), { type…

【机器学习】机器学习与大型预训练模型的前沿探索:跨模态理解与生成的新纪元

&#x1f512;文章目录&#xff1a; &#x1f4a5;1.引言 ☔2.跨模态理解与生成技术概述 &#x1f6b2;3.大型预训练模型在跨模态理解与生成中的应用 &#x1f6f4;4.前沿探索与挑战并存 &#x1f44a;5.未来趋势与展望 &#x1f4a5;1.引言 近年来&#xff0c;机器学习领…

解决Flutter位于悬浮窗口时,应用Logo不更新问题

问题描述 我已经更换了应用Logo&#xff0c;但是发现应用处于悬浮窗口时&#xff0c;logo还是更改之前的&#xff1f;下面的图片只是示意。 解决方案 终端命令 rm -rf ~/Library/Developer/Xcode/DerivedData2.xcode视图内解决 先在顶部找到 Xcode --> Setting --> Lo…

代码随想录算法训练营第十七天(py)| 二叉树 | 513.找树左下角的值、112. 路径总和、106.从中序与后序遍历序列构造二叉树

513.找树左下角的值 力扣链接 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 思路 层序遍历 层序遍历之后&#xff0c;取最后一个数组的第一个元素 class Solution:def findBottomLeftValue(self, root: Optional[TreeNode]) -> …

深入解析编程逻辑中的关键字与逻辑运算

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、认识关键字及其重要性 二、逻辑运算的关键字 1. and、or 和 not 的运用 2. 逻辑运算的…

世界上首位AI程序员诞生,AI将成为人类的对手吗?

3月13日&#xff0c;世界上第一位AI程序员Devin诞生&#xff0c;不仅能自主学习新技术&#xff0c;自己改Bug&#xff0c;甚至还能训练和微调自己的AI模型&#xff0c;表现已然远超GPT-4等“顶流选手”。 AI的学习速度如此之快&#xff0c;人类的教育能否跟上“机器学习”的速…

【C++算法】BFS解决单源最短路问题相关经典算法题

1.迷宫中离入口最近的出口 首先我们可以将这道题目简化一下&#xff0c;可以往我们这一章的主题上面来想想。 我们利层序遍历来解决最短路径问题&#xff0c;是最经典的做法。我们可以从起点开始层序遍历, 并组在遍历的过程中记录当前遍历的层数。这样就能在找到出口的时候&…

人工智能应用-实验7-胶囊网络分类minst手写数据集

文章目录 &#x1f9e1;&#x1f9e1;实验内容&#x1f9e1;&#x1f9e1;&#x1f9e1;&#x1f9e1;代码&#x1f9e1;&#x1f9e1;&#x1f9e1;&#x1f9e1;分析结果&#x1f9e1;&#x1f9e1;&#x1f9e1;&#x1f9e1;实验总结&#x1f9e1;&#x1f9e1; &#x1f9…

缓存IO与直接IO

IO类型 缓存 I/O 缓存 I/O 又被称作标准 I/O&#xff0c;大多数文件系统的默认 I/O 操作都是缓存 I/O。在 Linux 的缓存 I/O 机制中&#xff0c;数据先从磁盘复制到内核空间的缓冲区&#xff0c;然后从内核空间缓冲区复制到应用程序的地址空间&#xff08;用户空间&#xff0…

常见 JVM 面试题补充

原文地址 : 26 福利&#xff1a;常见 JVM 面试题补充 (lianglianglee.com) CMS 是老年代垃圾回收器&#xff1f; 初步印象是&#xff0c;但实际上不是。根据 CMS 的各个收集过程&#xff0c;它其实是一个涉及年轻代和老年代的综合性垃圾回收器。在很多文章和书籍的划分中&…