Java使用JNI自定义native方法(C++方法)

2023-05-16

IDE版本:IntelliJ Idea 2019、Visual Studio 2019

JDK版本:JDK 1.8

1)使用idea创建一个简单的java项目NativeTest。如下:

Main类的代码如下:

package com.native_test;

public class Main {
    private static native int multiply(int a, int b);
    static {
    }
    public static void main(String[] args) {
        System.out.println(multiply(2,3));
    }

2)选中Main类文件,右键,Open in Terminal,进到终端,输入如下命令:

javac Main.java -d ./

成功后,在当前目录下会多出一个com目录,最内层是编译成功的Main.class文件。

3)继续执行下面的语句:

javah -classpath ./ -jni com.native_test.Main

在当前目录下会生成一个头文件com_native_test_Main.h:

4)打开vs2019,创建一个c++空项目:

5)将刚才生成的头文件,复制到项目当前目录下:

6)回到vs中,点击显示所有文件,下面标红的按钮:

右键选中该文件,点击包括在项目中。取消显示所有文件,头文件就自动包含在了头文件文件夹里了。如果不是自动包含在头文件里面,也可以右键选中头文件夹,选择添加,选择现有项手动添加进来。

7)包含进来后,你会发现,里面是有错误的,这是因为缺少jni.h头文件。选择项目,右键=》属性。然后选择VC++ 目录,选择包含目录。

点击向下按钮,点击编辑,把jdk的两个目录win32和include包含进来:

点击确定,包含进来后,报错就消失了。

8)右键选择源文件,添加=》新建项,选择C++文件,命名为NativeMethod,点击添加:

9)在NativeMethod.cpp里面添加如下代码:

#include<iostream>
#include "com_native_test_Main.h"

using namespace std;

JNIEXPORT jint JNICALL Java_com_native_1test_Main_multiply
(JNIEnv* env, jclass jcl, jint a, jint b)
{
	return a * b;
}

10)右键选择项目,选择属性,把配置类型修改为动态库,然后右键选择项目,生成,就在当前项目目录的debug目录下自动生成了dll文件。注意,不是Java_Native_Method目录下的debug目录,而是和Java_Native_Method.sln文件平级的debug目录:

11)将最开始的java代码改为下面的代码:

package com.native_test;

public class Main {
    private static native int multiply(int a, int b);
    static {
        //采用静态路径加载
        System.load("E:\\Project\\C++\\Java_Native_Method\\Debug\\Java_Native_Method.dll");
        //该种方式要求把dll所在的目录加到系统环境变量中,或者把dll文件拷贝到该java项目的当前目录下
//        System.loadLibrary("Java_Native_Method");
    }
    public static void main(String[] args) {
        System.out.println(multiply(2,3));
    }
}

12)点击运行,输出内容如下:

运行成功。

如果你的系统是64位的,那么会报下面的错误:

Can't load IA 32-bit .dll on a AMD 64-bit platform

这个时候需要把c++的dll编译成64位的,方法是右键选择项目,选择属性,点击配置管理器,把下面标注的地方都改成64位:

这一步操作后需要重新做一下第七步的设置和第十步的配置类型设置。然后再重新生成,在debug的同级目录下会多出一个64的目录:

把Java代码里面的目录,改成这个目录,再点击运行,问题就解决了:

System.load("E:\\Project\\C++\\Java_Native_Method\\x64\\Debug\\Java_Native_Method.dll");

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java使用JNI自定义native方法(C++方法) 的相关文章

  • 如何消除 Java BoxLayout 中的间距?

    I programmed following ListPanel 使用 JavaScriptBoxLayout public class ListPanel extends JPanel private ArrayList
  • Android 中的 java.util.Observable 是线程安全的吗?

    Android 中的 java util Observable 是线程安全的吗 这文档 http developer android com reference java util Observable html说只有deleteObser
  • ListView:防止视图回收

    我有一个使用回收视图的 ListView 我试图阻止视图被回收 所以我使用 setHasTransientState android support v4 view ViewCompatJB setHasTransientState Vie
  • 探索java图像处理的好资源[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我是图像处理领域的新手 请推荐一些好的资源 书籍和网络链接 来学习 Java 中的图像处理 最适合隐写术分析 适合初学者和高级水平 我看过
  • 我应该使用 JDBC getNString() 而不是 getString() 吗?

    我们正在构建一个由 Oracle 数据库支持的 Java 应用程序 我们使用 JDBC 驱动程序 访问该数据库ojdbc6 jar and orai18n jar 数据库模式主要使用以下方式存储文本列NVARCHAR2数据类型 The JD
  • 为什么我的 @OneToMany 属性出现主键违规?

    我有一个实体 Entity public class Student GeneratedValue strategy GenerationType AUTO Id private long id OneToMany private Set
  • 外部实体更改后索引不更新

    我目前正在开发一个项目 使用 JPA 2 1 保存数据并使用 hibernate search 4 5 0 final 搜索实体 映射类和索引后 搜索工作正常 但是 当我更改值时描述B 类从 someStr 到 anotherStr 数据库
  • 为本地@ExceptionHandler编写JUnit测试

    我有以下控制器 class Controller ResponseStatus HttpStatus OK RequestMapping value verifyCert method RequestMethod GET public vo
  • 如何从 Java 中“double”类型的值中删除小数值

    我正在调用一个名为 calculateStampDuty 的方法 它将返回 财产需缴纳的印花税金额 百分比计算有效 很好 并返回正确的值 15000 0 但是 我想显示该值 前端用户只是 15000 所以只想删除小数点和任何前面的值 此后
  • 如何从 Trie 中检索给定长度的随机单词

    我有一个简单的 Trie 用来存储大约 80k 长度为 2 15 的单词 它非常适合检查字符串是否是单词 但是 现在我需要一种获取给定长度的随机单词的方法 换句话说 我需要 getRandomWord 5 来返回 5 个字母的单词 所有 5
  • 如何加载图像文件到ImageView?

    我试图在从文件选择器中选择图像文件后立即显示该图像文件 文件选择器仅限于 png 和 jpg 文件 所选文件存储在文件类型的变量中 为此 我设置了一个 ImageView 我希望用这个新文件设置图像 唯一的问题是它的类型是文件而不是图像 如
  • java中的第三个布尔状态是什么?

    虽然我知道根据定义 布尔值仅包含两种状态 真或假 我想知道布尔值在用这些状态之一初始化之前有什么值 它默认为 false http java sun com docs books tutorial java nutsandbolts dat
  • 在片段之间切换时底部导航栏会向下推

    在我的活动中 我有一个底部导航栏和框架布局来显示片段 一切正常 但问题是当我开始按顺序从 1 4 移动时 底部导航栏保持在其位置 但当我突然从 4 跳到2 然后底部导航栏就会超出屏幕 当再次单击同一项目时 它就会回到正常位置 该视频将清楚地
  • 如何在启用嵌入时间戳和 LTV 的情况下签署 PDF?

    我正在尝试签署启用了时间戳和 LTV 的 pdf 以便它在 Adob e Reader 中显示如下 在英语中 这意味着 签名包含嵌入的时间戳 和 签名启用了 LTV 这是我正在使用的代码 PrivateKey pk get pk from
  • Java给定长度的随机数

    我需要在 Java 中生成一个恰好 6 位数字的随机数 我知道我可以在随机发生器上循环 6 次 但是在标准 Java SE 中还有其他方法可以做到这一点吗 要生成 6 位数字 Use Random http download oracle
  • 线程上下文类加载器和普通类加载器的区别

    线程的上下文类加载器和普通类加载器有什么区别 也就是说 如果Thread currentThread getContextClassLoader and getClass getClassLoader 返回不同的类加载器对象 将使用哪一个
  • 测量 tomcat 的排队请求数

    因此 使用tomcat 您可以设置acceptCount值 默认为100 这意味着当所有工作线程都忙时 新连接被放置在队列中 直到队列满 之后它们被拒绝 我想要的是监视此队列中项目的大小 但无法确定是否有办法通过 JMX 获取此值 即不是队
  • AES 密钥是随机的吗?

    AES 密钥可以通过此代码生成 KeyGenerator kgen KeyGenerator getInstance AES kgen init 128 but 如果我有一个 非常可靠 的生成随机数的方法 我可以这样使用它吗 SecureR
  • 如何让JComboBox中的内容居中显示?

    目前我有这个JComboBox 我怎样才能将其中的内容居中 String strs new String 15158133110 15158133124 15158133458 JComboBox com new JComboBox str
  • 在 for 循环比较中使用集合大小

    Java 中 Collections 的 size 方法是否有编译器优化 考虑以下代码 for int i 0 i

随机推荐