加入收藏 | 设为首页 | 会员中心 | 我要投稿 拼字网 - 核心网 (https://www.hexinwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

java程序调用c++代码是你需要掌握的

发布时间:2021-05-25 23:02:57 所属栏目:语言 来源:互联网
导读:1、准备java代码 首先定义一个包含了native方法的类如下,之后我们要使用这个类中的native方法通过jni调用c++编写成的动态链接库中的方法: public classJniTest

首先定义一个包含了native方法的类如下,之后我们要使用这个类中的native方法通过jni调用c++编写成的动态链接库中的方法:

public class JniTest { 

    static{ 

        System.loadLibrary("MyNativeDll"); 

    } 

 

    public static native void callCppMethod(); 

 

    public static void main(String[] args) { 

        System.out.println("DLL path:"+System.getProperty("java.library.path")); 

        callCppMethod(); 

    } 

在代码中主要完成了以下工作:

在静态代码块中,调用loadLibrary方法加载本地的动态链接库,参数为不包含扩展名的动态链接库库文件名。在window平台下会加载dll文件,在linux平台下会加载so文件,在mac os下会加载jnilib文件

声明了一个native方法,native关键字负责通知jvm这里调用方法的是本地方法,该方法在外部被定义

在main方法中,打印加载dll文件的路径,并调用本地方法

2、生成头文件

在使用c/c++来实现本地方法时,需要先创建.h头文件。简单的来说,c/c++程序通常由头文件(.h)和定义文件(.c或.cpp)组成,头文件包含了功能函数、数据接口的声明,而定义文件用于书写程序的实现。

在jdk8中可以直接使用javac -h指令生成c/c++语言中的头文件。如果你使用的是较早版本的jdk,需要在执行javac编译完成class文件后,再执行javah -jni生成c/c++风格的头文件(在jdk10的新特性中已经删除了javah这一指令)。我们使用的jdk8简化了这一步骤,使其可以一步完成,在命令行窗口下执行命令:

javac -h ./jni JniTest.java 

指令中使用 -h参数指定放置生成的头文件的位置,最后的参数是java源文件的名称。在这个过程中完成了两件工作,首先生成class文件,其次在参数指定的目录下生成头文件。生成的头文件com_cn_jni_JniTest.h内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */ 

#include <jni.h> 

/* Header for class com_cn_jni_JniTest */ 

 

#ifndef _Included_com_cn_jni_JniTest 

#define _Included_com_cn_jni_JniTest 

#ifdef __cplusplus 

extern "C" { 

#endif 

/* 

 * Class:     com_cn_jni_JniTest 

 * Method:    callCppMethod 

 * Signature: ()V 

 */ 

JNIEXPORT void JNICALL Java_com_cn_jni_JniTest_callCppMethod 

  (JNIEnv *, jclass); 

 

#ifdef __cplusplus 

#endif 

#endif 

生成的头文件和大家熟悉的 java接口有些相似,只有函数的声明而没有具体实现。简单的解释一下头文件中的代码:

extern "C"告诉编译器,这部分代码使用C语言规则来进行编译

JNIEXPORT和JNICALL是jni中定义的两个宏,使用JNIEXPORT支持在外部程序代码中调用该动态库中的方法,使用JNICALL定义函数调用时参数的入栈出栈约定

函数名称由包名+类名+方法名组成,在该方法中有两个参数,通过第一个参数JNIEnv *的对象可以调用jni.h中封装好的大量函数 ,第二个参数代表着native方法的调用者,当java代码中定义的native方法是静态方法时这里的参数是jclass,非静态方法的参数是jobject

接下来我们创建一个cpp文件,引用头文件并实现其中的函数,也就是native方法将要实际执行的逻辑:

#include "com_cn_jni_JniTest.h" 

#include <stdio.h> 

  

JNIEXPORT void JNICALL Java_com_cn_jni_JniTest_callCppMethod 

  (JNIEnv *, jclass) 

    printf("Print From Cpp: n"); 

    printf("I am a cpp method ! n"); 

在方法的实现中加入简单的printf打印语句,在完成方法的实现后,我们需要将上面的cpp文件编译为动态链接库,提供给java中的native方法调用,因此下面需要在window环境下安装gcc环境。

(编辑:拼字网 - 核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!