一、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技术:参数为指针与结构体)的更多相关文章

  1. windows和linux环境下java调用C++代码-JNI技术

    最近部门做安卓移动开发的需要调C++的代码,困难重重,最后任务交给了我,查找相关资料,没有一个教程能把不同环境(windows,linux)下怎么调用说明白的,自己在实现的过程中踩了几个坑,在这里总结 ...

  2. Linux环境下如何计算CPU占用率【华为云技术分享】

    1.Linux 环境下查看 CPU 信息 1.1.查看 CPU 详细信息 通过 cat /proc/cpuinfo 命令,可以查看 CPU 相关的信息: [root@rh ~]$ cat /proc/ ...

  3. 解决Linux系统下程序找不到动态库的方法

    思路:一般来说,通过make命令已经将程序依赖的动态库编译出来了,通过make install命令已经将动态库安装到系统的某个路径下.找没找到动态库就看这个路径是否包含在系统默认搜索动态库的路径中,如 ...

  4. Windows 环境下Java调用CRF++详解

    1.步骤一览 2.步骤详情 2.1.环境准备 Swig(Simplified Wrapper and Interface Generator)下载,Windows操作系统直接解压即可使用 CRF++( ...

  5. Linux环境下Java中文乱码解决方案

    相信很多朋友遇到过Java的乱码问题,最近我也在解决一个“使用文本生成图片过程中中文以及特殊字符乱码”的问题:花了我大量时间,Debug了sun.font.sun.awt下面的各种源码,终于搞懂了其机 ...

  6. Linux环境下Java应用性能分析定位-CPU使用篇

    1     CPU热点分析定位背景 CPU资源还是很昂贵的,为了深刻感受到这种昂贵,间下图当前CPU的资源售价: 所以对于程序猿们来说,需要让程序合理高效的使用CPU资源.利用有限的CPU资源来解决完 ...

  7. windows和linux环境下使用google的glog日志库

    一.概述 glog是google推出的一款轻量级c++开源日志框架,源码在github上,目前最新release版本是v0.3.5. githut地址:https://github.com/googl ...

  8. Linux环境下的编译,链接与库的使用

    参考博客: http://www.cnblogs.com/qytan36/archive/2010/05/25/1743955.html http://m.blog.csdn.net/article/ ...

  9. 使用ctypes调用系统C API函数需要注意的问题,函数参数中有指针或结构体的情况下最好不要修改argtypes

    有人向我反应,在代码里同时用我的python模块uiautomation和其它另一个模块后,脚本运行时会报错,但单独使用任意一个模块时都是正常的,没有错误.issue链接 我用一个例子来演示下这个问题 ...

  10. Linux环境下java开发环境搭建二 tomcat搭建

    第一步:下载安装包并解压 # tar zxvf 压缩包名 第二步:把解压出的文件移动到/usr/local/tomcat7中 #mv 解压出来的文件夹  /usr/local/tomcat7 第三步: ...

随机推荐

  1. 记录--基于Vue2.0实现后台系统权限控制

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 基于Vue.js 2.x系列 + Element UI 的后台系统权限控制 前言:关于vue权限路由的那些事儿-- 项目背景:现有一个后台 ...

  2. WPF 组件间通信 MVVM 进行解耦

    假设有这样一个需求,有这样一个聊天界面,主界面是选项卡,其一选项卡内部是真正的聊天列表和聊天界面,我们需要实时的在主界面显示未读消息的数量 假设我们已经有方法可以拿到未读消息的数量,那么如何在主界面的 ...

  3. 任何样式,javascript都可以操作,让你所向披靡

    前言 习惯了在 css 文件里面编写样式,其实JavaScript 的 CSS对象模型也提供了强大的样式操作能力, 那就随文章一起看看,有多少能力是你不知道的吧. 样式来源 客从八方来, 样式呢, 样 ...

  4. 聊聊大模型"打字机"效果的背后技术——SSE

    SSE:Server Sent Event:服务器发送事件. Server-Sent Events(SSE)是一种由服务器向客户端推送实时数据的技术.它是构建基于事件的.服务器到客户端的通信的一种方法 ...

  5. GWD:基于高斯Wasserstein距离的旋转目标检测 | ICML 2021

      论文详细描述了当前旋转目标检测的主要问题,提出将旋转回归目标定义为高斯分布,使用Wasserstein距离度量高斯分布间的距离用于训练.目前,常规目标检测也有很多将回归转化为概率分布函数的做法,本 ...

  6. KingbaseES 扩展插件src_restrict 介绍

    插件简介 src_restrict是KingbaseES的一个扩展插件,主要用于支持来源限制功能,该功能通过黑白名单来实现.插件src_restrict默认已经加载. 查看插件是否加载 show sh ...

  7. .NET开源、免费、跨平台的Git可视化管理工具

    前言 俗话说得好"工欲善其事,必先利其器",合理的选择和使用可视化的管理工具可以降低技术入门和使用的门槛.今天大姚给大家分享一款.NET Avalonia开源.免费.跨平台.快速的 ...

  8. Final Countdown 题解

    Problem Link 简要题意 把一个数不断减一直到变成零,每个数位变化一次需要一秒. 比如 \(300\) 变成 \(299\) 需要 \(3\) 秒. 求把一个数变成零要多少秒. 思路 对于每 ...

  9. #拉格朗日插值,线性筛#洛谷 5442 【XR-2】约定 (加强版)

    题目 一个\(n\)个点的完全图, 第\(i\)个点到第\(j\)个点的边权是\((i+j)^k\), 现在把这个完全图变成一棵树, 求这棵树边权和的期望值 \((n\leq 10^{10000},k ...

  10. #莫比乌斯反演,整除分块,欧拉定理#U137539 虚伪的最小公倍数

    题目 \[\large\prod_{i_1=1}^n\prod_{i_2=1}^n\dots\prod_{i_k=1}^n\frac{i_1*i_2*\dots*i_k}{gcd(i_1,i_2,\d ...