JNI编程Demo----Java程序调用C&C++编译好的库文件
来源:互联网 发布:centos7源码安装nginx 编辑:程序博客网 时间:2024/06/15 06:19
JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。下面用一个Demo实现通过JNI,Java如何调用C&C++的库文件(Windows下是dll文件,Linux下是so文件)。
本文在Windows下实现,因此调用的是dll文件,期间也会说明linux下调用so文件有什么不同之处,环境如下:
- 操作系统:Win10 Pro
- JDK:1.7(1.8也完全ok)
- IDE:Jetbrains IDEA 2016.3 Community
一、安装GCC环境
Windows下,一般选择安装MinGW,下载地址:下载地址,安装好后,将MinGW安装目录下的bin目录加入PATH中,然后打开命令行,输入gcc -v,出现如下信息即证明安装完成:
二、JNI Demo
首先用IDEA创建一个Java工程,在src目录下创建一个包,包名为cn.hust.demo,如图:
在该包下编写类TestAdd,我们要实现的功能是两个数相加:package cn.hust.demo;// Created by LCJ on 2017.7.21.public class TestAdd { static { System.loadLibrary("Add"); } private native int add(int a, int b); public static void main(String[] args) { int c = new TestAdd().add(3, 4); System.out.println("Result is: " + c); }}
方法System.loadLibrary()用来加载dll(windows)或so(Linux)库,只需名称即可,无需加入文件名后缀(.dll或.so)。native关键字将函数add(int a, int b)声明为本地函数,由C/C++实现。具体的实现就在Add.dll(Windows平台)或libAdd.so(Linux平台)中。注意,在Linux平台下,so文件前面要有“lib”前缀(但是System.loadLibrary()的参数仍然和Windows下一样,不用带“lib”),否则会找不到库文件。
生成头文件
首先将TestAdd.java编译一下,出现TestAdd.class:
然后配置生成头文件的命令:
File–>Settings–>Tools–>External Tools,点击右边的“+”号,如下填写:
Name为“Generate Header File”,上图中Tool Settings部分的填写:
Program:$JDKPath$/bin/javah
;
Parameters:-jni -classpath $OutputPath$ -d ./jni $FileClass$
Working Dictionary:$ProjectFileDir$
如此配置好后,在TestAdd.java文件上右键,选择External tools–>Generate Header File:
即生成了头文件如下:
代码如下:/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class cn_hust_demo_TestAdd */#ifndef _Included_cn_hust_demo_TestAdd#define _Included_cn_hust_demo_TestAdd#ifdef __cplusplusextern "C" {#endif/* * Class: cn_hust_demo_TestAdd * Method: add * Signature: (II)I */JNIEXPORT jint JNICALL Java_cn_hust_demo_TestAdd_add (JNIEnv *, jobject, jint, jint);#ifdef __cplusplus}#endif#endif
在此代码中,函数命名为Java_<包>_<类名>_<函数名>,参数中除前两个参数外,后面两个是add函数的参数类型,jint对应int型。
编写C语言文件
在jni目录下编写add.c文件:
代码:#include <jni.h>#include <stdio.h>#include "cn_hust_demo_TestAdd.h"JNIEXPORT jint JNICALL Java_cn_hust_demo_TestAdd_add(JNIEnv *env, jobject o, jint a, jint b){jint c = a + b;printf("The sum of %d + %d is: %d", a, b, c);return c;}
编译C语言文件,生成dll库
仍然同生成头文件一样,用IDEA的external tools一键生成dll文件。因此打开external tool配置界面,点击“+”号,创建一个名为“Generate DLL”(如果是Linux环境下,你就命名为“Generate SO”)的tool:
具体配置如下:
Program:D:\Program Files\MinGW\mingw64\bin\gcc.exe
即你的gcc目录,Linux下也同样是gcc路径
Parameters:-Wl,--add-stdcall-alias -I"$JDKPath$\include" -I"$JDKPath$\include\win32" -shared -o ./lib/$FileNameWithoutExtension$.dll ./jni/$FileNameWithoutExtension$.c
注意,如果是Linux环境下,win32要改成linux,dll文件的文件名也要改,前面要加上lib前缀,同时是so文件而非dll文件,命令细节也要更改,最终如此:-I"$JDKPath$\include" -I"$JDKPath$\include\linux" -fPIC -shared -o ./lib/lib$FileNameWithoutExtension$.so ./jni/$FileNameWithoutExtension$.c
Working dictionary:$ProjectFileDir$
配置好后,在工作目录下新建lib文件夹,然后右键Add.c,选择external tools中的“Generate DLL”,在lib目录下生成DLL文件:
运行Java程序,得出结果
此时,运行一开始的java程序会报错找不到库文件:
这时,需要在运行参数中配置如下:
将VM options中加入:-Djava.library.path=I:\IDEAWorkspace\JNI\TestJNIDemo\lib
即library path指向DLL文件所在目录即可。
此时再运行java程序,即得出正确结果:
三、附注
本文展示了生成头文件、写C语言程序和生成库文件的全过程Demo,一般情况下,是直接拿到库文件进行调用的,因此前面的过程可以略去,只需知道该库文件哪些函数可以调用,直接用Java进行调用即可。
- JNI编程Demo----Java程序调用C&C++编译好的库文件
- java JNI调用c程序
- JAVA通过JNI调用C函数Demo
- Java通过JNI调用C的一个小DEMO
- Java通过JNI调用C的一个小demo
- Chap5:使用JNI技术实现java程序调用第三方dll(c/c++)文件的功能
- 使用JNI技术实现java程序调用第三方dll(c/c++)文件的功能
- java高级编程,JNI的使用。java代码调用c程序
- java高级编程,JNI的使用。c程序调用java代码
- java通过jni调用c编译的dll或so
- Java的JNI:使用Java调用C程序(入门)
- Java的JNI:使用Java调用C程序(一)
- 【Java】Java调用C/C++程序的实现(jni)
- Windows 7下,java jni调用C程序demo,编译器为mingw
- java通过jni调用C程序
- jni实现C语言调用Java程序
- Java JNI调用c/c++程序
- JNI小程序:Java通过JNI调用C程序
- PhpStorm的REST client使用
- Ubiquitous Religions
- linux : 做一个干净的debian7.5.0的开发环境
- 如何使用echo指令向文件写入内容
- Android 系统服务的注册以及 getService() 方法源码解析
- JNI编程Demo----Java程序调用C&C++编译好的库文件
- Oracle 12c RAC 搭建手册
- css选择器
- Exception:Request processing failed; nested exception is org.apache.ibatis.binding.BindingException
- 插入排序
- 如何在Ubuntu终端下使用SS
- Jenkins+ant+jmeter 配置
- 非比较排序---【归并排序】
- 开发配置