zoukankan      html  css  js  c++  java
  • JNI入门

    JNI是Java Native Interface的缩写,Native指C/C++。

    JNI内容涉及两个方面:

    • Java调用C,这种情况是最主要的
    • C调用Java,这种情况不常见

    第一步:编写Java代码

    package haha;
    public class Haha {
    public native int add(int x, int y);
    
    public native int sub(int x, int y);
    
    public static void main(String[] args) {
       System.loadLibrary("haha");
       Haha haha = new Haha();
       int x = haha.add(3, 6);
       System.out.println(x);
       x = haha.sub(3, 6);
       System.out.println(x);
    }
    }
    

    定义一个类Haha,它包括两个方法:add和sub,分别是加法和减法。使用Native关键字表明这两个方法是本地方法,无需在Java中给出实现。

    注意:加载dll时,不需要带.dll后缀

    第二步:javah命令生成头文件

    本项目目录结构如下:src/haha/Haha.java,控制台进入到src/目录下,使用javah命令分析haha.Haha.java文件,生成头文件。
    javah haha.Haha
    注意:

    • javah是jdk安装之后自带的命令,使用之前请确保jdk/bin在环境变量Path中。
    • javah haha.Haha,不需要后缀名.java

    第三步:编写C代码

    打开VisualStudio,新建win32项目,选择dll作为项目类型。

    默认分成头文件、源文件、资源文件三个文件夹,没有必要,把这三个文件夹删掉。

    新建haha_Haha.h头文件,把第二步中生成的头文件内容复制进来。
    右键项目属性,在VC++/包含目录中,添加JDK/include和JDK/include/win32这两个文件夹(用分号隔开),不要删除原来已经有的目录。

    新建“源.cpp”,include 那个头文件,并给出实现:

    #include"haha_Haha.h"
    
    JNIEXPORT jint JNICALL Java_haha_Haha_add
    (JNIEnv *env, jobject obj, jint x, jint y){
    	return x + y;
    }
    
    JNIEXPORT jint JNICALL Java_haha_Haha_sub
    (JNIEnv *env, jobject obj, jint x, jint y){
    	return x - y;
    }
    
    

    最后,点击菜单“生成/生成解决方案(快捷键F7)”或者“生成/重新生成解决方案”,就会在debug目录下找到dll了。

    复制上面的dll路径,准备去IntelliJ里面试试能不能加载这个dll

    第四步:添加dll运行Java代码

    直接运行Java代码会报错:
    Exception in thread "main" java.lang.UnsatisfiedLinkError: no haha in java.library.path

    看来,必须让java知道dll在哪里,这可以通过java.library.path属性来实现。
    点击菜单“Run/Edit Configuration”添加java运行参数

    这时运行CTRL+SHIFT+F10运行代码,报错了:
    Can't load IA 32-bit .dll on a AMD 64-bit platform
    看来,生成的dll是32位的,而我的JDK是64位的(我的系统是64位的)。

    切换到VS中,更改项目属性/配置属性,选择64位平台(如果没有x64,点击配置管理器新建平台即可)。之后重新生成dll。

    会发现此时dll的目录也发生了改变,所以需要更改java.library.path参数(这个参数跟jar包的classpath是两回事)。

    再次运行,终于成功了。

    最后

    本文只是JNI的入门小例子,更多内容参考《Java核心技术 卷二:高级特性》最后一章。
    JNI包括:

    • Java和C中数据类型的对应关系,尤其是String类型,C只支持ASCII码,而Java中的String是Unicode范围。
    • C中代码访问Java静态成员的变量和方法
    • C中代码访问Java对象的成员变量和方法
    • C中变量资源申请和释放
    • C中代码访问Java数组
  • 相关阅读:
    为什么说LD_LIBRARY_PATH不好
    linux c/c++ code统计耗时
    c++: abs() 与fabs() 的区别
    char代表有符号还是无符号?
    git三个小技巧:删除指定 commit、修改历史 commit 中的作者信息、合并某文件到当前分支
    vim选中字符复制/剪切/粘贴
    git rebase
    git打patch
    数据仓库生命周期工作箱 第六章 维度建模
    数据仓库生命周期工作箱 第二章 项目/项目群的启动与管理
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/7260906.html
Copyright © 2011-2022 走看看