JNI编程Demo----Java程序调用C&C++编译好的库文件

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 __cplusplus
    extern "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进行调用即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值