linux环境下java调用C/C++动态库(JNI技术:参数为指针与结构体)
一、JNI技术
JNI是Java Native Interface的缩写,通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植.
SUN公司发布的Java 本地接口(JNI)提供了将Java与C/C++、汇编等本地代码集成的方案,该规范使得在 Java 虚拟机内运行的 Java 代码能够与其它编程语言互相操作,包括创建本地方法、更新Java对象、调用Java方法,引用 Java类,捕捉和抛出异常等,也允许Java代码调用 C/C++或汇编语言编写的程序和库。作为一个标准程序接口,它没有对底层 Java虚拟机的实现施加任何限制(特点:二进制兼容、效率高、功能强)
java与JNI数据类型对照表
1、基本数据类型
2、引用数据类型对照表
二、Linux环境的准备(centos7)
1、安装JDK(注意:不能安装openjdk,因为openjdk没有include目录,编译时需要用到include目录的头文件)
2、安装gcc和g++ ( yum install gcc-c++)
3、新建Java工程,在包名为com.ywb.Native下新建"NativeCpp.java"类,方法必须使用native修饰(native即 JNI java native interface)
package com.ywb.Native; public class NativeCpp { public native void sayHello(); public native int calculate(int num1, int num2); public native void output(String url, String newUrl);
}
4、编译生成class文件,进入工程下的target\classes目录下,执行"javah -jni com.ywb.Native.NativeCpp",生成"com_ywb_Native_NativeCpp.h"头文件
4.1:com_ywb_Native_NativeCpp.h文件内容
#include <jni.h>
/* Header for class com_ywb_Native_NativeCpp */ #ifndef _Included_com_ywb_Native_NativeCpp
#define _Included_com_ywb_Native_NativeCpp
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_ywb_Native_NativeCpp
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_ywb_Native_NativeCpp_sayHello
(JNIEnv *, jobject); /*
* Class: com_ywb_Native_NativeCpp
* Method: calculate
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_ywb_Native_NativeCpp_calculate
(JNIEnv *, jobject, jint, jint); /*
* Class: com_ywb_Native_NativeCpp
* Method: output
* Signature: (Ljava/lang/String;Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_ywb_Native_NativeCpp_output
(JNIEnv *, jobject, jstring, jstring); #ifdef __cplusplus
}
#endif
#endif
5、创建c++源码文件( vim jni.cpp),将生成的头文件"com_ywb_Native_NativeCpp.h"拷贝过来,#include "jni.h"改为#include <jni.h>,再加上自己需要实现的c++代码逻辑
#include <jni.h>
/* Header for class com_ywb_Native_NativeCpp */ #ifndef _Included_com_ywb_Native_NativeCpp
#define _Included_com_ywb_Native_NativeCpp
#ifdef __cplusplus
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
extern "C" {
#endif
/*
* * Class: com_ywb_Native_NativeCpp
* * Method: sayHello
* * Signature: ()V
* */
JNIEXPORT void JNICALL Java_com_ywb_Native_NativeCpp_sayHello
(JNIEnv *, jobject){
printf("hello world\n");
} /*
* * Class: com_ywb_Native_NativeCpp
* * Method: calculate
* * Signature: (II)I
* */
JNIEXPORT jint JNICALL Java_com_ywb_Native_NativeCpp_calculate
(JNIEnv *, jobject, jint num, jint newNum){
return num + newNum;
} char* jstringToChar(JNIEnv* env, jstring jstr) {
char* rtn = NULL;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("GB2312");
jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
jsize alen = env->GetArrayLength(barr);
jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
if (alen > 0) {
rtn = (char*) malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
env->ReleaseByteArrayElements(barr, ba, 0);
return rtn;
}
/*
* * Class: com_ywb_Native_NativeCpp
* * Method: output
* * Signature: (Ljava/lang/String;Ljava/lang/String;)V
* */
JNIEXPORT void JNICALL Java_com_ywb_Native_NativeCpp_output
(JNIEnv *env, jobject, jstring url, jstring newUrl){
char* pUrl1 = jstringToChar(env, url);
char* pUrl2 = jstringToChar(env, newUrl);
printf("url1 = %s\n", pUrl1);
printf("url2 = %s\n", pUrl2); } #ifdef __cplusplus
}
#endif
#endif
6、编译生成动态库
6.1:g++ -fPIC -c jni.cpp -I /home/admin/software/jdk1.8.0_202/include/ -I /home/admin/software/jdk1.8.0_202/include/linux/
6.2:g++ -shared jni.o -o jni.so
7、java调用c++动态库
package com.ywb.Native; public class App { public static void main( String[] args )
{
//windows环境下加载库
//System.load("D:\\\JniDll.dll"); //linux下加载库
System.load("/root/IdeaProjects/demo/target/classes/jni.so"); NativeCpp nativeCpp = new NativeCpp();
nativeCpp.sayHello();
System.out.println(nativeCpp.calculate(15, 15));
nativeCpp.output("www.baidu.com", "https://www.cnblogs.com/ywbmaster/www.haoservice.cn");
}
}
注:可以将代码封装成jar包,为以后程序方便调用
8、jni方法签名规则
可以进入Java编译后的class文件所在的目录,执行 javap -s 对应Java类的class文件,可以查看当前类下所有方法所对应的签名信息
1、方法例子:
public void example1(int string, float index)
对应签名:
(IF)V
2、方法例子:
public string example2(String string, int index,double d)
对应签名:
(Ljava/util/String;I;D)Ljava/util/String;
3、方法例子:
public int example3(int index, String value,int[] arr)
对应签名:
(ILjava/util/String;[I)I
linux环境下java调用C/C++动态库(JNI技术:参数为指针与结构体)的更多相关文章
- windows和linux环境下java调用C++代码-JNI技术
最近部门做安卓移动开发的需要调C++的代码,困难重重,最后任务交给了我,查找相关资料,没有一个教程能把不同环境(windows,linux)下怎么调用说明白的,自己在实现的过程中踩了几个坑,在这里总结 ...
- Linux环境下如何计算CPU占用率【华为云技术分享】
1.Linux 环境下查看 CPU 信息 1.1.查看 CPU 详细信息 通过 cat /proc/cpuinfo 命令,可以查看 CPU 相关的信息: [root@rh ~]$ cat /proc/ ...
- 解决Linux系统下程序找不到动态库的方法
思路:一般来说,通过make命令已经将程序依赖的动态库编译出来了,通过make install命令已经将动态库安装到系统的某个路径下.找没找到动态库就看这个路径是否包含在系统默认搜索动态库的路径中,如 ...
- Windows 环境下Java调用CRF++详解
1.步骤一览 2.步骤详情 2.1.环境准备 Swig(Simplified Wrapper and Interface Generator)下载,Windows操作系统直接解压即可使用 CRF++( ...
- Linux环境下Java中文乱码解决方案
相信很多朋友遇到过Java的乱码问题,最近我也在解决一个“使用文本生成图片过程中中文以及特殊字符乱码”的问题:花了我大量时间,Debug了sun.font.sun.awt下面的各种源码,终于搞懂了其机 ...
- Linux环境下Java应用性能分析定位-CPU使用篇
1 CPU热点分析定位背景 CPU资源还是很昂贵的,为了深刻感受到这种昂贵,间下图当前CPU的资源售价: 所以对于程序猿们来说,需要让程序合理高效的使用CPU资源.利用有限的CPU资源来解决完 ...
- windows和linux环境下使用google的glog日志库
一.概述 glog是google推出的一款轻量级c++开源日志框架,源码在github上,目前最新release版本是v0.3.5. githut地址:https://github.com/googl ...
- Linux环境下的编译,链接与库的使用
参考博客: http://www.cnblogs.com/qytan36/archive/2010/05/25/1743955.html http://m.blog.csdn.net/article/ ...
- 使用ctypes调用系统C API函数需要注意的问题,函数参数中有指针或结构体的情况下最好不要修改argtypes
有人向我反应,在代码里同时用我的python模块uiautomation和其它另一个模块后,脚本运行时会报错,但单独使用任意一个模块时都是正常的,没有错误.issue链接 我用一个例子来演示下这个问题 ...
- Linux环境下java开发环境搭建二 tomcat搭建
第一步:下载安装包并解压 # tar zxvf 压缩包名 第二步:把解压出的文件移动到/usr/local/tomcat7中 #mv 解压出来的文件夹 /usr/local/tomcat7 第三步: ...
随机推荐
- Oracle 常用建库模板
记录一下 create tablespace lxw_tablespace datafile '/oradata/orcl/lxw_data_01.ora' size 30G; --或者 create ...
- 鸿蒙HarmonyOS实战-ArkUI组件(mediaquery)
一.mediaquery 1.概述 媒体查询(mediaquery)它允许根据设备的不同特性(如屏幕大小.屏幕方向.分辨率.颜色深度等)来动态地调整网页的样式和布局. 通过媒体查询,可以为不同的设备定 ...
- 立创EDA的使用
立创EDA的使用 1.实验原理 最近在使用立创EDA来做电路作业,这里记录一下立创EDA的基本操作,以后小型的电路设计可以在其主页完成.立创EDA是一个可以线上完成电路设计仿真以及布线的免费设计工具, ...
- ARM之AXI总线协议初试
AXI总线协议的学习 1.AXI总线的初步认识 What is AXI? AXI is part of ARM AMBA, a family of micro controller buses fir ...
- KingbaseES V8R6 集群运维案例 -- 脚本部署集群后ssh无法连接
案例说明: 在kylin V10环境下,通过脚本方式部署KingbaseES V8R6集群后,发现ssh无法连接主机,通过分析发现在脚本部署过程中会对系统环境进行优化配置,在修改了/etc/ssh/s ...
- #差分约束系统,最长路,线段树优化建边#洛谷 3588 [POI2015] PUS
题目 给定一个长度为\(n\)的正整数序列 \(a\) ,每个数都在 \(1\) 到 \(10^9\) 范围内, 告诉你其中 \(s\) 个数,并给出 \(m\) 条信息,每条信息包含三个数 \(l, ...
- #min_max容斥#HDU 4336 Card Collector
题目 有\(n\)张牌,获得第\(i\)张牌的概率为\(p_i\), 问期望多少次能收集完\(n\)张牌 分析 题目求的是\(E(\max S)\),根据min_max容斥可以得到, \[E(\max ...
- Jetty的bytebufferpool模块
bytebufferpool模块用于配置Jetty的ByteBuffer对象的对象池. 通过对象池的方式来管理ByteBuffer对象的使用和生命周期,期望降低Jetty进程内存的使用,同时降低JVM ...
- OpenHarmony社区运营报告(2023年8月)
本月快讯 ● 2023年8月3日,OpenAtom OpenHarmony(以下简称"OpenHarmony")发布了Beta2版本.OpenHarmony 4.0 Beta2 ...
- AI云增强升级!还原生动人像,拍出质感照片
近期不少细心用户发现,在用HUAWEI Mate 60 Pro手机拍照后,使用相册中的AI云增强功能,照片变得更加细腻有质感.这是因为AI云增强升级并更新支持了人像模式拍摄的照片,高清自然的人像细节还 ...