使用Java调用C/C++
文章目录
- 前言
- 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代码
注意
- 调用本地代码的java方法,要设置成native的。
- 要使用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++相关推荐
- eclipse java调用c 代码吗_linux下通过eclipse开发用java调用c程序的方法
linux下通过eclipse开发用java调用c程序的方法: 1.先建立好java工程并建立java文件如下: public class testso { static { ...
- Java调用C/C++编写的第三方dll动态链接库(zz)
这里主要用的方法是JNI.在网上查资料时看到很多人说用JNI非常的复杂,不仅要看很多的文档,而且要非常熟悉C/C++编程.恐怕有很多人在看到诸如此类的评论时已经决定绕道用其他方法了.本文将做详细的介绍 ...
- 使用JNA,让java调用原生代码
JNA定义: JNA:java Native Access,是SUN公司开发的基于JNI的框架.JNI使得Java可以调用原生的c或者c++代码. JNA与JNI(Java Native Interf ...
- java无阻塞执行脚本,JAVA调用Shell脚本-及阻塞的解决方法
JAVA调用Shell脚本--及阻塞的解决办法 用java调用shell,使用 Process p=Runtime.getRuntime().exec(String[] cmd); Runtime.e ...
- Java 调用Oracle的存储过程
2019独角兽企业重金招聘Python工程师标准>>> 1.创建存储过程的语句: 1.表结构:①:create table TESTA(A_ID VARCHAR2(10) not n ...
- Java调用ocx控件以及dll
2019独角兽企业重金招聘Python工程师标准>>> http://lvqingboy-163-com.iteye.com/blog/769358 通过Java调用OCX控件有几种 ...
- java 调用c/c++
2019独角兽企业重金招聘Python工程师标准>>> java 调用c/c++ 第一步: 编写java程序:如-- public class Pxy { static{ //加载动 ...
- java调用cd传输_Java调用Linux命令(cd的处理)
一.Java调用Linux系统的命令非常简单 这是一个非常常用的调用方法示例: 1 publicString executeLinuxCmd(String cmd) {2 System.out.pri ...
- 用Java调用WebService
这是一个用Java调用C#版WebService接口的例子: C#接口: Java代码 <SPAN style="FONT-SIZE: 11px"> using Sys ...
- pytorch移动端教程 Java调用libtorch
将模型转为libtorch模型之后 剩下的就是移动端是事情了 也就是使用java调用模型因为 libtorch 支持移动端且支持java调用 其实你使用java再电脑做做测试最好 但是不得不说libt ...
最新文章
- 干货 | 一文搞懂极大似然估计
- 微信小程序实现滚动到指定位置
- mybatis 多租户saas_MybatisPlus 多租户架构(SaaS)实现
- 使用python学线性代数_最简单的神经网络简介| 使用Python的线性代数
- 直播连麦贾扬清,谈谈他所理解的四大 AI 落地问题 | 攻“疫”技术公开课
- 通过共现矩阵和余弦相似度实现机器对单词的认知、python实现
- js使用const的好处_let和const命令
- 小程序入门学习09--云开发02
- 【删库不跑路】—Linux系统自杀实验 rm -rf /* 及如何抢救和预防
- java gbk文件转utf8_java 将GBK编码文件转为UTF-8编码
- javaweb开发后端常用技术_Java web开发需要学习哪些技术?
- SpringBoot集成海康威视Linux版本
- Java堆栈的简单图示
- 移动web UI推荐
- r语言和python语法对比_R语言和Python区别对比,你会选择哪一个?
- 三七互娱U3D面试记录
- 几行代码,把你的小电影全部藏好了!
- mmo服务器 性能测试,【Zinx应用-MMO游戏案例-(5)构建项目及用户上线】Golang轻量级并发服务器框架...
- 20 C++ 秒数转换时分秒
- Java微信支付API文档测试