Linux上从Java程序中调用C函数
原则上来说,“100%纯Java”的解决方法是最好的,但有些情况下必须使用本地方法。特别是在以下三种情况:
- 需要访问Java平台无法访问的系统特性和设备;
- 通过基准测试,发现Java代码比其他语言编写的等价代码慢得多;
- 其他语言编写的代码已经经过大量测试和调试,并且知道如何将其导出到所有的目标平台上。
Java平台有一个用于和本地C、C++代码进行互操作的API,称为Java本地接口(JNI)。下面将举例讨论Linux平台下的JNI编程。
1. 创建java类文件
创建一个nativeTest包,在包下新建HelloNative.java文件。
package nativeTest; /**
* Created by jiax on 2016/12/30.
*/
public class HelloNative {
// 静态初始化代码块,保证虚拟机在第一次使用该类时就会装载库
static {
System.loadLibrary( "HelloNative" );
} // native 关键字表示本地方法,提醒编译器该方法将在外部定义
public static native void greeting(); // 测试greeting()函数
public static void main(String[] args) {
greeting();
}
}
2. 生成.h头文件
使用以下命令生成一个C的头文件,nativeTest_HelloNative.h
javac HelloNative.java
cd ..
javah nativeTest.HelloNative
生成的nativeTest_HelloNative.h如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class nativeTest_HelloNative */ #ifndef _Included_nativeTest_HelloNative
#define _Included_nativeTest_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: nativeTest_HelloNative
* Method: greeting
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_nativeTest_HelloNative_greeting
(JNIEnv *, jclass); #ifdef __cplusplus
}
#endif
#endif
nativeTest_HelloNative.h
这个文件是在nativeTest文件夹外生成的,需要拖到nativeTest文件夹里面。
3. 创建.c文件
新建一个HelloNative.c文件,写出greeting()函数的实现代码。
#include <stdio.h>
#include "nativeTest_HelloNative.h" JNIEXPORT void JNICALL Java_nativeTest_HelloNative_greeting(JNIEnv *env, jobject c1) {
printf("Hello Native!!\n");
}
4. 编译一个动态链接库
使用Linux下的gcc编译器,命令如下:
gcc -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -shared -o libHelloNative.so HelloNative.c
生成libMyNative.so文件,此时整个nativeTest目录文件结构如下:
5. 运行测试
输入如下命令运行HelloNative.class文件。
java nativeTest.HelloNative
如果出现如下错误:
则需要把libHelloNative.so所在文件夹加入java.library.path,使用命令:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:..../nativeTest
最终结果如下。
6 总结
总的来说,将一个本地方法链接到Java程序中需要经过以下5个步骤:
- 在Java类中声明一个本地方法;
- 运行javah以获得包含该方法的C声明的头文件;
- 用C实现该本地方法;
- 将代码置于共享类库中;
- 在Java程序中加载该类库。
附录——本文中用到的工具版本
JDK——1.8.0_111
gcc——4.8.5
Linux上从Java程序中调用C函数的更多相关文章
- 在网页程序或Java程序中调用接口实现短信猫收发短信的解决方案
方案特点: 在网页程序或Java程序中调用接口实现短信猫收发短信的解决方案,简化软件开发流程,减少各应用系统相同模块的重复开发工作,提高系统稳定性和可靠性. 基于HTTP协议的开发接口 使用特点在网页 ...
- Java程序中调用Python脚本的方法
在程序开发中,有时候需要Java程序中调用相关Python脚本,以下内容记录了先关步骤和可能出现问题的解决办法. 1.在Eclipse中新建Maven工程: 2.pom.xml文件中添加如下依赖包之后 ...
- 如何在java程序中调用linux命令或者shell脚本
转自:http://blog.sina.com.cn/s/blog_6433391301019bpn.html 在java程序中如何调用linux的命令?如何调用shell脚本呢? 这里不得不提到ja ...
- java程序中调用Linux命令Windows命令
目前总结的方法: 调用Linux简单的命令行,设置文件夹权限755 String scriptDir = "/home/wenf"; String cmd = "chmo ...
- Linux上分析java程序的问题
通过日志看不出来的问题,可以通过看java的堆栈信息(dump文件)来看出一些端倪. 1. 找java的进程id.jdk/bin的目录 ps -ef | grep java 2. cd 到bin的目录 ...
- Android驱动入门-在Android系统上运行JAVA程序
在linux上运行java程序,直接用javac编译,再用java运行就行了.但是在Android上,由于虚拟机和pc端的不同,所以操作方法也是不一样的. 如果想在Android上运行Hello wo ...
- linux(ubuntu) 搭建java程序运行环境
一:简介 ubuntu 系统的和linux差不多,我们需要在系统上搭建java程序运行环境,需要安装jdk,mysql这两个软件,tomcat是绿色版,直接通过taz -zxvf tomcat 就可以 ...
- 如何在 Linux 上安装应用程序
如何在 Linux 上安装应用程序 编译自:https://opensource.com/article/18/1/how-install-apps-linux作者: Seth Kenlon原创:LC ...
- 如何使用加多宝(jdb)在linux下调试Java程序
毕业时写了一段时间的C,那时候调试使用gdb,后来转了java,当时就想java程序怎么调试,找了一下,果然,那就是jdk自带的jdb windows里是这样的 Linux下是这样的 一般我在linu ...
随机推荐
- java.util.zip获取Zip文件条目InputStream
package com.test; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import ja ...
- Java 005 枚举
枚举概述:就是有有限值的集合或类.是指将变量的值一一列出来, 变量的值只限于列举出来的值得范围. 举例: 一周7天, 一年12个月等.回想单列设计模式: 单例类是一个类只有一个实例.那么多例类就是一个 ...
- angular $scope对象
$scope是一个pojo对象 $scope提供了一些工具方法.例如:$watch() $apply(),一般不会手工去调用 $scope是表达式的执行环境也叫作用域 $scope是一个树形结构,与D ...
- C# 构造post参数一种看起来直观点的方法[转]
因为本人经常爱用C#做一些爬虫类的小东西,每次构造post参数的时候,都是直接字符串拼接的方式的,有时候改起来不太方便. 场景: 需要post一个地址 参数列表 : username:管理员 pass ...
- ACM集训的1B。。。。黑色星期五。。。。2333333
题目: 印象中有好多个13号是星期五,13号在星期五比在其他日子少吗?为了回答这个问题,写一个程序,要求计算每个月的十三号落在周一到周日的次数.给出N年的一个周期,要求计算1900年1月1日至1900 ...
- ps用画笔工具设计水墨圆环
1.打开ps,新建一个1500*1500px的空白文档,分辨率为72,背景选择白色,如图: 2.选择画笔工具,按F5调出画笔预设面板,设置参数. 画笔笔尖形状:选择27号画笔,找不到可以复位一下画笔: ...
- Python开发【十二章】:ORM sqlalchemy
一.对象映射关系(ORM) orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却 ...
- inotify监控目录变化重启服务器tornado项目
pycharm 配置了提交服务器项目每次pycharm修改后,虽然保存到服务器但是项目还得自己去服务器kill再启动.就花几分钟写了shell脚本用于监控项目目录变化并重启tornado项目的脚本 如 ...
- centos7 web服务器内核优化
net.ipv4.tcp_syn_retries = 1net.ipv4.tcp_synack_retries = 1net.ipv4.tcp_keepalive_time = 600net.ipv4 ...
- 用android去写一个小程序
前言: 软工的一个小作业:实现"黄金分割小游戏", 需要结对编程,队友:陈乐云 共用时两天. 早期思路设计: 采用键值对的形式,以Map作为存储结构.优点:能够将数据与用户对 ...