2019-1-4日,记录一下这两天使用jni调用C++的过程

项目有一个需要控制ipc的功能,我之前取巧用了visca协议,走网口的,结果同组的C++的同事听闻我这样控,问了我控制方法,发现我这样控制很简单,而他使用onvif协议写了很多内容,遂验证该协议是否能对其他大厂的IPC进行控制,测了一个海康威视的摄像头就不行了,上网查了一下发现visca协议大多支持串口,网口实现的较少,相比之下Onvif协议比较通用,遂准备重新实现Onvif协议,刚开始写这个功能的时候也了解过,但是因为较麻烦又刚好从其他人那里知道了visca协议才没有实现,确实很麻烦,然后向C++同事请教控制流程,问过之后听他说可以用Java直接调C++的方法,我之前确实学完就忘了,然后重新学了一遍Jni,踩了不少坑记录一下

1.创建一个类,里面有 native 修饰的方法,可以是 static 修饰的

import java.util.Map;

public class Hello {
    public native String hello(Map map);

}

 2. 类路径下使用dos命令 {javac 类.java} ,编译出class 文件

1 C:\>javac Hello.java

3. 类路径下使用{javah 类名},生成 .h文件在同一路径下

1 C:\>javah Hello

这个地方有一个坑,刚开始测试的时候在类路径下这样执行是没问题的,但是正式放入项目中使用时报错了,

1 package com.x.hello;

放在项目中使用时要根据在package的最外层包下执行,也就是包含这个包com,项目路径下的src文件下执行,生成的文件在执行dos命令的路径下

1 C:\>javah -classpath . -jni 包名.类名

4. 打开VS2019(其他版本均可,我习惯性下最高版本),创建一个空项目

点击源文件,添加,类,头文件名改为生成文件名,然后点击添加,

2019-1-4日,记录一下这两天使用jni调用C++的过程

 5.打开头文件中生成的 头文件,把javah编译后生成的头文件内容复制到里面

2019-1-4日,记录一下这两天使用jni调用C++的过程

 这一步第一次的话也有一个坑,需要打开项目的属性页,点击c/C++,在附加目录中添加Java底层C++文件的路径,jdk安装目录下include文件夹和include文件夹下的win32文件夹,

如:

C:/jdk/include

C:/jdk/include/win32

2019-1-4日,记录一下这两天使用jni调用C++的过程

6. 打开源文件在添加的类中放入以下内容

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

using namespace std;

JNIEXPORT void JNICALL Java_Hello_hello(JNIEnv* env, jobject f)
{
     printf("hello123");
}

点击项目名生成即可。

需要注意的是这个设置内容需要和Java安装的环境一样,在这里32位不兼容64位,暂不清楚原因

2019-1-4日,记录一下这两天使用jni调用C++的过程

 7. 根据生成路径,在路径下找到 后缀位 .dll 和项目同名的文件,复制到C:/windows/system32  下即可

2019-1-4日,记录一下这两天使用jni调用C++的过程

 2019-1-4日,记录一下这两天使用jni调用C++的过程

 8. 打开Hello.java ,添加main方法调用native修饰方法,调用前使用

System.loadLibrary("C++项目名,不要后缀");

,试试效果,刚开始时也可直接写main方法,不过其中刚开始写可能会有语法问题,所以不建议生成头文件时就写main方法

package com.xh.server.utils;

public class OnvifUtil {
    static {
        System.loadLibrary("OnvifUtil");
    }

    public native void hello();

    public static void main(String[] args){
        OnvifUtil onvifUtil = new OnvifUtil();
       
        onvifUtil.hello();

    }

}

相关推荐