欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JNI接口 创建一个Java调用C++实例 涉及JAVA与C++之间的参数传递问题

程序员文章站 2022-07-07 19:32:31
一.背景某项目需要一个工业视觉系统,系统方面用Java+Vue做业务数据存储,参数配置,系统间交互。其中需要调用底层C++封装的DLL算法。用到JNI接口,调用时主要涉及到图片数据以及一些配置参数传递,数据返回。新建一个简单的JNI接口实现Java和C++交互。二.实例开发工具:IDEA,JDK8,VS20192.1新建Java JNI接口public class JniDemo {//方法一 返回名称 public native String getName(); //方...

一.背景

某项目需要一个工业视觉系统,系统方面用Java+Vue做业务数据存储,参数配置,系统间交互。其中需要调用底层C++封装的DLL算法。用到JNI接口,调用时主要涉及到图片数据以及一些配置参数传递,数据返回。新建一个简单的JNI接口实现Java和C++交互。

二.实例

开发工具:IDEA,JDK8,VS2019

2.1新建Java JNI接口

public class JniDemo {
	
	//方法一 返回名称
    public native String getName();
    //方法二 传递一个参数
    public native void sayAWord(String prompt);
    
}

2.2生成Java文件对应的C++(.h)头文件

第一种方法 直接用jvm命令运行
在控制台输入javah -jni com.jni.JniDemo,注意要包含包路径
JNI接口 创建一个Java调用C++实例  涉及JAVA与C++之间的参数传递问题
第二种方法 在IDEA中配置External Tools
IDEA中点击File->Setting->External Tools 点击+
JNI接口 创建一个Java调用C++实例  涉及JAVA与C++之间的参数传递问题

  • Name: Generate Header File(可随意指定)
  • Program: D:\Program Files\Java\jdk1.8.0_131\bin\javah (javah所在的目录)
  • Arguments: -jni -classpath $OutputPath$ -d ./jni $FileClass$
  • Working directory:$ProjectFileDir$
    在Java文件上右击点击External Tools生成头文件

JNI接口 创建一个Java调用C++实例  涉及JAVA与C++之间的参数传递问题
生成的.h文件为项目目录下jni文件夹里
JNI接口 创建一个Java调用C++实例  涉及JAVA与C++之间的参数传递问题

2.3. VS2019中实现.h文件生成dll

2.3.1.vs2019中创建动态链接库工程

JNI接口 创建一个Java调用C++实例  涉及JAVA与C++之间的参数传递问题

2.3.2对工程做一些设置

注意选择运行环境为x64:
JNI接口 创建一个Java调用C++实例  涉及JAVA与C++之间的参数传递问题
右键项目添加包含目录
JNI接口 创建一个Java调用C++实例  涉及JAVA与C++之间的参数传递问题
设置包含路径

  • F:\jni; //.h头文件所在的目录
  • D:\Program Files\Java\jdk1.8.0_131\include; //jni.h所在的目录
  • D:\Program Files\Java\jdk1.8.0_131\include\win32;

新建一个com_ainnovation_ai_business_jni_JniDemo.cpp文件包含刚才的头文件,实现定义的方法

#include "com_ainnovation_ai_business_jni_JniDemo.h"
#include <iostream>
using namespace std;
JNIEXPORT jstring JNICALL Java_com_ainnovation_ai_business_jni_JniDemo_getName
(JNIEnv* env, jobject obj)
{
	cout << "You are the apple of mine" << endl;
}

JNIEXPORT void JNICALL Java_com_ainnovation_ai_business_jni_JniDemo_sayAWord
(JNIEnv* env, jclass cla)
{
	const char* str;
	str = env->GetStringUTFChars(prompt, JNI_FALSE);
	std::cout << str << std::endl;
	env->ReleaseStringUTFChars(prompt, str);
}

2.4 点击生成DLL

点击运行若发现报错是否忘记了向源中添加“#include “pch.h”
右击项目属性-C/C++ 预编译头 不使用预编译头
JNI接口 创建一个Java调用C++实例  涉及JAVA与C++之间的参数传递问题
JNI接口 创建一个Java调用C++实例  涉及JAVA与C++之间的参数传递问题

三 Java调用jni接口

package com.ainnovation.ai.business.jni;
public class JniDemo {

    public native String getName();
    public native static void sayAWord();

    static{
        //注意把Person.dll文件放入java.library.path这一jvm变量所指向的路径中
        //System.out.println(System.getProperty("java.library.path"));
        //第一种方式:System.loadLibrary("JniDemo");
        System.load("F:\\jni\\JniDemo.dll");//第二种
    }

    public static void main(String[] args) {
        JniDemo jniDemo = new JniDemo();
        System.out.println(jniDemo.getName());
        jniDemo.sayAWord();
    }
}

两种加载DLL方式

  • System.loadLibrary 需要把生成的DLL放在java.library.path这一jvm变量所指向的路径中。例如(System.loadLibrary(“JniDemo”);
  • System.load 直接加载绝对路径下的 例如System.load(“F:\jni\JniDemo.dll”);

运行结果:
JNI接口 创建一个Java调用C++实例  涉及JAVA与C++之间的参数传递问题

本文地址:https://blog.csdn.net/kuaidi2883/article/details/107161039