文章目录

  • 前言
  • JNI概述
  • 例子
    • 编写Java代码
    • 编译生成的class文件:JNITest.class
    • 在命令行下使用javah生成C/C++头文件。在工程的bin目录下输入以下命令:
    • 实现C++代码。在VS2008中创建一个Win32 project,类型为DLL。
    • 构建C++项目
    • 将dll文件复制到Java工程的bin目录下

前言

我们知道Java是一种平台无关性的语言,平台对于上层的java代码来说是透明的,所以在多数时间我们是不需要调用本地方法,但是假如你遇到了以下情况,你可能就需要使用Java调用本地方法了:

1、你的Java代码需要得到一个文件的属性。但是你找遍了JDK帮助文档也找不到相关的API。
2、在本地还有一个别的系统,不过它不是Java语言实现的,这个时候你需要把两套系统整合到一起。
3、你的Java代码中需要用到某种算法,不过算法是用C实现并封装在动态链接库文件(DLL)当中的。

对于上述的三种情况,如果没有JNI的话,那就会变得异常棘手了。JNI其实是Java Native Interface的简称,也就是java本地接口。它提供了若干的API实现了和Java和其他语言的通信(主要是C&C++)。
在Java中有一些native方法,这些方法只有方法签名但是没有方法体。其实这些naive方法就是我们说的 java native interface。它提供了一个调用(invoke)的接口,然后用C或者C++去实现。

JNI概述

JVM封装了各种操作系统实际的差异性的同时,提供了JNI技术,它是一种双向的接口,使得开发者可以通过Java代码调用到各种native的库,反之亦然。所以JNI(Java Native Interface)能作为Java语言的一部分,她能够作为粘合剂将Java应用和其他本地应用(C/C++,Delphi)集合在一起。

作为一个双向的接口,JNI能支持两种native代码:native libraries 和native applications。

你能使用JNI去写一些native methods去允许Java Applications能呼叫native libraries中的函数,native methods的具体
实现是可能C,C++或者Delphi。
JNI也支持嵌入一个JVM实现到一个本地应用程序中去,去执行那些用Java语言编写的的模块.比如,一个C++编写的
浏览器利用内嵌的JVM去执行下载到本地的applet。

实现步骤:

1、完成Java代码,编写好Java调用类。
2、编译你的Java类。
3、用javah生成编译好的class文件对应的C/C++ 函数的头文件。
4、实现头文件中的函数原型,编写native代码。
5、将native代码编译打包成DLL库(win32)或共享库(Linux)。
6、将你的Java代码跑起来

例子

编写Java代码

注意

  1. 调用本地代码的java方法,要设置成native的。
  2. 要使用System的LoadLibrary方法去加载包含本地方法实现的库。
    Java代码
package eric.test;
public class JNITest {           static {  System.loadLibrary("JNITest");  }           public static native void sayHelloWorld(String msg);           public static void main(String[] args) {  sayHelloWorld("Hello, world");  }
}

编译生成的class文件:JNITest.class

在命令行下使用javah生成C/C++头文件。在工程的bin目录下输入以下命令:

cmd代码

javah -classpath . -jni eric.test.JNITest

将生成头文件eric_test_JNITest.h,内容如下:
app代码

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class eric_test_JNITest */  #ifndef _Included_eric_test_JNITest
#define _Included_eric_test_JNITest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     eric_test_JNITest
* Method:    sayHelloWorld
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_eric_test_JNITest_sayHelloWorld  (JNIEnv *, jclass, jstring);  #ifdef __cplusplus
}
#endif
#endif

注意,在执行javah的时候,要输入完整的包名和类名。否则在以后的测试调用过程中会发生java.lang.UnsatisfiedLinkError这个异常。

实现C++代码。在VS2008中创建一个Win32 project,类型为DLL。

将刚才生成的头文件eric_test_JNITest.h拷到工程目录下,并且在项目中导入到Header Files里面。打开StdAfx.h文件,在最后面添加:
cpp代码

#include "jni.h"
#include "eric_test_JNITest.h"

打开JNITest.cpp文件,在其中添加实现代码。函数名为头文件中定义的函数声明。
app代码

#include <iostream>
using namespace std;  JNIEXPORT void JNICALL Java_eric_test_JNITest_sayHelloWorld  (JNIEnv* env, jclass method, jstring param)
{  const char* pt = env->GetStringUTFChars(param, 0);   cout << pt << " called by Java Native Interface" << endl;
}

其中,GetStringUTFChars是jre中提供的jni方法,用来得到java string的字符串。

构建C++项目

会出现"Cannot open include file: ‘jni.h’: No such file or directory"的错误,解决方法是将以下文件拷贝到C++工程目录下

%JAVA_HOME%\include\jni.h
%JAVA_HOME%\include\win32\jni_md.h

同时将头文件eric_test_JNITest.h中的 #include <jni.h> 改为
cpp代码

#include "jni.h"

然后重新build,将在debug目录下生成JNITest.dll文件。

将dll文件复制到Java工程的bin目录下

(这个位置十分重要,否则会出现not found的异常),并运行程序
cmd代码

java eric.test.JNITest

将输出结果"Hello, world called by Java Native Interface"。

使用Java调用C/C++相关推荐

  1. eclipse java调用c 代码吗_linux下通过eclipse开发用java调用c程序的方法

    linux下通过eclipse开发用java调用c程序的方法: 1.先建立好java工程并建立java文件如下: public class testso {     static {         ...

  2. Java调用C/C++编写的第三方dll动态链接库(zz)

    这里主要用的方法是JNI.在网上查资料时看到很多人说用JNI非常的复杂,不仅要看很多的文档,而且要非常熟悉C/C++编程.恐怕有很多人在看到诸如此类的评论时已经决定绕道用其他方法了.本文将做详细的介绍 ...

  3. 使用JNA,让java调用原生代码

    JNA定义: JNA:java Native Access,是SUN公司开发的基于JNI的框架.JNI使得Java可以调用原生的c或者c++代码. JNA与JNI(Java Native Interf ...

  4. java无阻塞执行脚本,JAVA调用Shell脚本-及阻塞的解决方法

    JAVA调用Shell脚本--及阻塞的解决办法 用java调用shell,使用 Process p=Runtime.getRuntime().exec(String[] cmd); Runtime.e ...

  5. Java 调用Oracle的存储过程

    2019独角兽企业重金招聘Python工程师标准>>> 1.创建存储过程的语句: 1.表结构:①:create table TESTA(A_ID VARCHAR2(10) not n ...

  6. Java调用ocx控件以及dll

    2019独角兽企业重金招聘Python工程师标准>>> http://lvqingboy-163-com.iteye.com/blog/769358 通过Java调用OCX控件有几种 ...

  7. java 调用c/c++

    2019独角兽企业重金招聘Python工程师标准>>> java 调用c/c++ 第一步: 编写java程序:如-- public class Pxy { static{ //加载动 ...

  8. java调用cd传输_Java调用Linux命令(cd的处理)

    一.Java调用Linux系统的命令非常简单 这是一个非常常用的调用方法示例: 1 publicString executeLinuxCmd(String cmd) {2 System.out.pri ...

  9. 用Java调用WebService

    这是一个用Java调用C#版WebService接口的例子: C#接口: Java代码 <SPAN style="FONT-SIZE: 11px"> using Sys ...

  10. pytorch移动端教程 Java调用libtorch

    将模型转为libtorch模型之后 剩下的就是移动端是事情了 也就是使用java调用模型因为 libtorch 支持移动端且支持java调用 其实你使用java再电脑做做测试最好 但是不得不说libt ...

最新文章

  1. 干货 | 一文搞懂极大似然估计
  2. 微信小程序实现滚动到指定位置
  3. mybatis 多租户saas_MybatisPlus 多租户架构(SaaS)实现
  4. 使用python学线性代数_最简单的神经网络简介| 使用Python的线性代数
  5. 直播连麦贾扬清,谈谈他所理解的四大 AI 落地问题 | 攻“疫”技术公开课
  6. 通过共现矩阵和余弦相似度实现机器对单词的认知、python实现
  7. js使用const的好处_let和const命令
  8. 小程序入门学习09--云开发02
  9. 【删库不跑路】—Linux系统自杀实验 rm -rf /* 及如何抢救和预防
  10. java gbk文件转utf8_java 将GBK编码文件转为UTF-8编码
  11. javaweb开发后端常用技术_Java web开发需要学习哪些技术?
  12. SpringBoot集成海康威视Linux版本
  13. Java堆栈的简单图示
  14. 移动web UI推荐
  15. r语言和python语法对比_R语言和Python区别对比,你会选择哪一个?
  16. 三七互娱U3D面试记录
  17. 几行代码,把你的小电影全部藏好了!
  18. mmo服务器 性能测试,【Zinx应用-MMO游戏案例-(5)构建项目及用户上线】Golang轻量级并发服务器框架...
  19. 20 C++ 秒数转换时分秒
  20. Java微信支付API文档测试

热门文章

  1. 为什么自学Python看不进去?转头就忘?
  2. 字符串匹配: BF与KMP算法
  3. JRE和JDK区别(jvm.dll和jar包的作用)
  4. 华为综合测试备考笔记
  5. 精心整理的15道 Dubbo 基础面试题,拿去!
  6. mysql 注解_四种mysql注释实例
  7. Java单元测试实践-00.汇总(9万多字文档+700多测试示例)
  8. 精选了20个Python实战项目(附源码),拿走就用!零基础练手不二项目!
  9. layui 动态表格 templet模板函数
  10. Java系列之:可变参数和可变参数的使用