linux中Java程序调用C程序中方法的实现方式浅析

在Linux中,Java程序可以通过JNI(Java Native Interface)来调用C程序的方法。

在这里插入图片描述在这里插入图片描述

Linux系统环境,Java调用C的主要流程如下:
1、创建Java类文件,如NativeLibrary.java
2、编写Java代码,加载.so共享库(C程序生成该名称的.so共享库),并声明本地方法
3、使用javac编译Java类,生成.class文件
4、使用javah对.class文件生成C头文件,该文件包含了Java和C之间通信所需的函数声明
5、创建C语言源文件,如NativeLibrary.c
6、编写C程序代码并实现要被Java调用的方法
7、使用gcc编译C程序和C头文件生成动态链接库(共享库.so文件)
8、运行Java程序,并调用C程序中的方法

1、Java类文件

创建NativeLibrary.java文件,内容如下:

public class NativeLibrary {static {System.loadLibrary("mylib"); // 加载名为"mylib"的共享库}public native void printHello(); // 声明本地方法public static void main(String[] args) {new Hello().printHello(); // 调用本地方法}
}

其中,System.loadLibrary(“mylib”);为加载共享库, public native void printHello();为声明本地方法。

在Java中,加载本地库(通常是C或C++编写的库,以.dll、.so或.dylib等形式存在)主要有两种方式:System.loadLibrary()和System.load()。这两种方法用于与Java Native Interface (JNI)交互,使Java程序能够调用本地代码。
使用 System.loadLibrary()允许Java运行时根据平台自动定位和加载本地库。你只需要提供库的名字(不包括扩展名,如.dll或.so),Java运行时会在标准位置搜索这些库。
使用 System.load()允许你直接指定本地库的完整路径。这在库不在标准位置或需要加载特定版本的库时非常有用。
当使用System.loadLibrary()时,通常需要在linux环境设置环境变量LD_LIBRARY_PATH,如export LD_LIBRARY_PATH=“.so文件所在路径”

2、C头文件

javah是Java的一个命令行工具,用于生成JNI(Java Native Interface)的C或C++头文件。这些头文件包含了Java方法的本地签名,允许C或C++代码调用这些方法。当你需要编写本地代码来实现Java方法时,javah生成的头文件是非常有用的。
假设你有一个Java类MyClass,它位于包org.example中,并且你想要为这个类生成JNI头文件。以下是你需要遵循的步骤:

  1. 编写java类
  2. 编译java类,使用javac命令编译Java源文件。这一步骤会生成.class文件,javah工具需要这些文件才能工作。如,javac org/example/MyClass.java,注意.java文件所在的路径
  3. 使用javah生成C头文件,需要指定类的全限定名(包括包名)。如,javah -jni org.example.MyClass
  4. 生成.h文件,如org_example_NativeLibrary.h

C头文件内容如下

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_example_NativeLibrary */#ifndef _Included_org_example_NativeLibrary
#define _Included_org_example_NativeLibrary
#ifdef __cplusplus
extern "C" {
#endif
/** Class:     org_example_NativeLibrary* Method:    printHello* Signature: ()V*/
JNIEXPORT void JNICALL Java_org_example_NativeLibrary_printHello(JNIEnv *, jobject);#ifdef __cplusplus
}
#endif
#endif

3、C程序文件

创建C程序文件,如NativeLibrary.c,内容如

#include <jni.h>
#include "org_example_NativeLibrary.h"JNIEXPORT void JNICALL Java_org_example_NativeLibrary_printHello(JNIEnv *env, jobject obj) {printf("Hello from C!\n");
}

其中,#include <jni.h>的jni.h文件来自jdk环境下,#include "NativeLibrary.h"来自使用javah生成的C头文件,Java_org_example_NativeLibrary_printHello需要和C头文件中的方法名称抱持一致。

4、共享库.so文件

编译C程序和头文件生成共享库,命令如下

gcc -shared -fpic -o libmylib.so -I$JAVA_HOME/include -I$JAVA_HOME/include/linux NativeLibrary.c

其中 libmylib.so为生成的共享库文件, -I J A V A H O M E / i n c l u d e − I JAVA_HOME/include -I JAVAHOME/includeIJAVA_HOME/include/linux为找C程序中的jni.h依赖,NativeLibrary.c为C程序文件,且C头文件需要和C程序文件在同一目录下。
在执行编译之前,请确保已经安装了gcc编译器,以及jdk环境。

5、运行Java程序

在linux环境中将.so共享库文件所在路径加入java.library.path中,设置环境变量,如下

export LD_LIBRARY_PATH=".so文件所在路径"
java ***类或java -jar ***包

结果类似如下
在这里插入图片描述

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

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

相关文章

mysql中的datetime类型在Java中到底对应哪个时间类型?

因为MySQL中用的是datetime类型&#xff08;年月日 时分秒&#xff09; java.sql.Date 在Java中用 java.sql.Date 接收 但是得到的却只有年月日 前端接收到的是时间戳 java.time.LocalDateTime 在Java中使用 java.time.LocalDateTime 接收 得到的是带时区的时间 前端接收到的…

ROS中的TF是什么

在ROS (Robot Operating System) 中&#xff0c;tf::TransformBroadcaster 是一个用于发布坐标变换信息的重要类&#xff0c;尤其在处理机器人定位和导航数据时非常常见。tf::TransformBroadcaster 对象允许你广播从一个坐标系到另一个坐标系的变换关系&#xff0c;这对于多传感…

web中间件漏洞-Redis漏洞未授权访问漏洞-写webshell、写ssh公钥

web中间件漏洞-Redis漏洞未授权访问漏洞 利用redis未授权访问漏洞写webshell 利用redis未授权访问、攻击机向服务器写入webshell 从服务器查看写入的webshell 菜刀连接 利用redis未授权访问漏洞写ssh公钥 kali生成rsa公私钥对 ssh-keygen -t rsa 将公钥id_rsa.pub写入文…

33 - 连续出现的数字(高频 SQL 50 题基础版)

33 - 连续出现的数字 -- 开窗函数lead(col,n) 统计窗口内往下第n行值 -- over(partition by xxx) 按照xxx所有行进行分组 -- over(partition by xxx order by aaa) 按照xxx分组&#xff0c;按照aaa排序select distinct num as ConsecutiveNums from(select num,# 从当前记录获…

C语言第17篇:预处理详解

1、预定义符号 C语言设置了一些预定义符号&#xff0c;可以直接使用。预定义符号也是在预处理期间处理的。 __FILE__ //进行编译的源文件 __LINE__ //文件当前的行号 __DATE__ //文件被编译的日期 __TIME__ //文件被编译的时间 __STDC__ //如果编译器遵循ANSI…

【Streamlit学习笔记】Streamlit-ECharts箱型图添加均值和最值label

Streamlit-ECharts Streamlit-ECharts是一个Streamlit组件&#xff0c;用于在Python应用程序中展示ECharts图表。ECharts是一个由百度开发的JavaScript数据可视化库Apache ECharts 安装模块库 pip install streamlitpip install streamlit-echarts绘制箱型图展示 在基础箱型…

Apple - Launch Services Programming Guide

本文翻译整理自&#xff1a;Launch Services Programming Guide https://developer.apple.com/library/archive/documentation/Carbon/Conceptual/LaunchServicesConcepts/LSCIntro/LSCIntro.html#//apple_ref/doc/uid/TP30000999-CH201-TP1 文章目录 一、导言谁应该阅读此文档…

【Linux】基础IO_4

文章目录 六、基础I/O4. 动静态库 未完待续 六、基础I/O 4. 动静态库 既然我们能够成功创建静态库了&#xff0c;接下来我们将这个代码打包成动态库&#xff1a; shared: 表示生成共享库格式 fPIC&#xff1a;产生位置无关码(position independent code) 动态库库名规则&…

bug记录——C语言中运算符前假后面不执行

A&&B A为真&#xff0c;才会判断B&#xff0c; 所以如果B访问越界的情况下必有A为假&#xff0c;那么代码是正确的 像这里&#xff0c;当child 1 > n时&#xff0c;a[child 1]越界访问&#xff0c; 但由于&&前面判断了child 1 < n为假&#xff0c;所以…

IDEA快速入门02-快速入门

二、快速入门 2.1 打开IDEA,点击New一个项目 入口&#xff0c;依次打开 File -> New -> Project。 2.2 使用Spring Initializr方式构建Spring Boot项目 2.3 设置项目所属组、项目名称、java版本等 2.4 选择SpringBoot版本及依赖组件 点击Create进行创建。 2.6 创建成…

windows10远程桌面端口,Windows 10远程桌面端口修改的两个方法

在Windows 10系统中&#xff0c;远程桌面功能允许用户通过网络从一台计算机远程访问和控制另一台计算机。默认情况下&#xff0c;远程桌面服务使用的端口是3389。然而&#xff0c;出于安全考虑&#xff0c;许多管理员和用户希望修改这一默认端口。本指南将详细介绍如何在Window…

WPS没保存关闭了怎么恢复数据?4个方法(更新版)

想象一下&#xff0c;你正在用WPS奋笔疾书&#xff0c;灵感如泉水般涌出&#xff0c;突然间&#xff0c;电脑却跟你开了个玩笑——啪地一下&#xff0c;文档未保存就关闭了&#xff01;是不是感觉像是被泼了一盆冷水&#xff0c;所有的热情瞬间熄灭&#xff1f;别急&#xff0c…

代码随想录第31天|贪心算法

134. 加油站 参考 思路: 以每个油站相差作为判断, 比如: gas [5 8 2 8]cost [6 5 6 6] [-1 3 -4 2]错误 : 把相差最大点当作起点判断能否绕一圈 : 相加数组是否小于0局部最优: 当前累加rest[i]的和curSum一旦小于0&#xff0c;起始位置至少要是i1&#xff0c;因为从i…

SQLite数据库(数据库和链表双向转换)

文章目录 SQLite数据库一、SQLite简介1、SQLite和MySQL2、基于嵌入式的数据库 二、SQLite数据库安装三、SQLite的常用命令四、SQLite的编程操作1、SQLite数据库相关API&#xff08;1&#xff09;头文件&#xff08;2&#xff09;sqlite3_open()&#xff08;3&#xff09;sqlite…

vue3 computed与watch,watchEffect比较

相同点 都是要根据一个或多个响应式数据进行监听 不同点 computed 如要return回来一个新的响应式值&#xff0c;且这个值不允许直接修改&#xff0c;想要修改的话可以设置set函数&#xff0c;在函数里面去修改所依赖的响应式数据&#xff0c;然后计算属性值会基于其响应式依…

【秋招刷题打卡】Day02-二分系列之-二分查找

Day02-二分系列之-二分查找 前言 给大家推荐一下咱们的 陪伴打卡小屋 知识星球啦&#xff0c;详细介绍 >笔试刷题陪伴小屋-打卡赢价值丰厚奖励 < ⏰小屋将在每日上午发放打卡题目&#xff0c;包括&#xff1a; 一道该算法的模版题 (主要以力扣&#xff0c;牛客&#…

基于CPWM与DPWM综合调制的光伏逆变器

1. 光伏并网逆变器矢量控制 图 1 为光伏发电系统常用的逆变器拓扑结 构,太阳能光伏电池板发电所产生的直流电能接 入光伏并网逆变器直流侧。逆变器将电能逆变, 经过滤波器与隔离升压变压器连接,最终并入电 网。其中隔离变压器低压侧漏感与LC滤波器组 成LCL滤波。为便于分析…

android | studio的UI布局和代码调试 | UI调试 (用于找到项目源码)

网上找到一个项目&#xff0c;想快速的搞懂是怎么实现的&#xff0c;搞了半天发现原来android都升级到Jetpack Compose了&#xff0c;然后去找源码挺不容易的&#xff0c;摸索中发现了这个调试的方法&#xff0c;还可以。 https://developer.android.com/studio/debug/layout-i…

谷歌Chrome浏览器排查js内存溢出

1. 打开谷歌浏览器检查台 2. 点击memory 3. 点击开始快照录制&#xff0c;时隔一会儿录一次&#xff0c;多录几次 4. 进行快照对比

【C++】STL中优先级队列的使用与模拟实现

前言&#xff1a;在前面我们学习了栈和队列的使用与模拟实现&#xff0c;今天我们来进一步的学习优先级队列使用与模拟实现 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质量&#xff23;学习 &#x1f448; &#x1f4af;代码仓库:卫…