c++调用powershell_Java调用C++程序过程及问题解决

1、Java调用C++程序过程

Java作为一种跨平台语言,通过虚拟机的机制能够很好的将代码迁移到各个平台,但是有时候需要调用平台底层的功能,这时候往往需要利用C/C++语言进行底层代码的编写以达到很好的性能。那如何使Java能够方便的调用C/C++程序呢?本文将以一个“hello Word”基础程序给你讲解如何利用Java调用C++程序(该技术称为JNI技术)。其主要过程包括5步骤:1、编写Java本地调用程序;2、对Java程序进行编译;3、编写C/C++实现代码;4、生成动态库(dll);5、进行调用。

1.1 编写Java本地调用程序

先上代码,如下所示:

public class JNITest {    static {        System.loadLibrary("JNITest");  // 1、定义需要加载的dll库名称    }    public static native void sayHelloWorld(String msg); // 2、利用native关键字定义调用接口    public static void main(String[] args) {        sayHelloWorld("Hello, world");  // 3、在主方法中进行调用    }}

主要包含3个部分,首先通过System.loadLibrary()方法进行dll文件的声明,让Java程序知道需要加载哪个dll文件;其次利用native关键字定义Java调用C/C++语言的接口,该接口将由C/C++进行具体实现,注意在方法前一定要标注native关键字,因为利用native关键字标注的方法,让Java虚拟知道该方法的实现是由外部程序实现,而不是由Java程序实现;最后为了方便后面的调试,需要定义一个主方法并对sayHelloWorld进行调用。

1.2 对Java程序进行编译

在Windows系统通过菜单键+R并输入cmd命令,调出命令行窗口,并通过cd命令,将执行目录切换到1.1步骤中java文件所在的文件目录中。然后在命令行中输入javac JNITest.java对该java文件进行编译,如下图所示:

8673bf567ab203741b5cc1ca1bb2f626.png

Java程序进行编译

在这个过程中需要注意两点问题,首先JDK的路径是否加入到系统的环境变量中;其次如果java文件带有包地址,需要将java文件的包地址写上。

输入上述命令后,在java文件所在的目录下将生成JNITest.class文件,该文件就是编译后的文件。然后在命令行中输入javah JNITest将生成C/C++的头文件(JNITest.h),如下图所示:

cc7e2b12126514ea475c8e1bef1661f2.png

生成头文件

/* DO NOT EDIT THIS FILE - it is machine generated */#include jni.h/* Header for class JNITest */#ifndef _Included_JNITest#define _Included_JNITest#ifdef __cplusplusextern "C" {#endif/* * Class:     JNITest * Method:    sayHelloWorld * Signature: (Ljava/lang/String;)V */JNIEXPORT void JNICALL Java_JNITest_sayHelloWorld  (JNIEnv *, jclass, jstring);#ifdef __cplusplus}#endif#endif

从上面的代码可以看出在JNITest.h文件中定义了java中的native接口。

1.3 编写C/C++实现代码

首先在vs2019 “文件-》新建-》项目”中创建C++动态程序,其创建过程如下图所示:

e80ec8cfca0adcd76a7d0ce6537a056c.png

新建dll库

然后在右侧的项目中点击“源文件”并鼠标右键,依次选择“添加-新建项”,将弹出如下界面,并选择“C++文件”,来创建空白C++文件。

742420011206ecc04fd4272f1547dd01.png

创建新的C++文件

再然后将JNITest.h中的声明方法拷贝到该文件中并实现具体的实现。代码如下图所示:

#include "pch.h"#include "JNITest.h"   // 1.申明引用的头文件,该头文件就是用javah生成的头文件// 2.该方法申明,必须要与JNITest中的声明一致,JNIEXPORT void JNICALL Java_JNITest_sayHelloWorld    (JNIEnv *env, jclass, jstring string) {// 3.具体实现,获取java传过来的参数进行输出const char* str = env->GetStringUTFChars(string, 0);char cap[128];strcpy_s(cap, str);//env->ReleaseStringUTFChars(string, str);printf(str);}

然后,在VS2019右边的项目目录中点击“头文件”鼠标右键,并依次点击“添加-》现有项”,将用javah生成的JNITest.h头文件添加到项目中,添加后如下图所示:

beb7e5039839986ee504a60886085d74.png

1.4 生成动态库(dll)

编写好代码后,在vs2019右边的项目目录中,点击项目名称,并点击鼠标右键,在弹出的选择框中选择“生成”对代码进行编译。编译成功后,将会在项目的debug文件下生成相应的dll文件,其余文件不用管。如下图所示:

e0332b05e6c75837699971a2d01a4a31.png

生成dll结果

1.5 进行调用

将1.4中生成的dll拷贝到1.1中的java文件夹下,并将dll文件的名称更改为JNITest(该名称需要与System.loadLibrary()一致),然后在命令行中输入“java JNITest”,将出现如下结果,说明调用成功。

17ae27109639a51224937c5bd10352e9.png

进行调用

2、出现的问题及解决过程

在实际的开发过程中,出现了两种问题,现将遇到的问题及解决方法,与大家进行分享。

1、报错无法找到jni文件

在C/C++程序进行编译的过程,出现如下的编译错误,如下图所示:

e67187fad7e668cad43c618e83e606aa.png

这说明vs环境未能找到jni.h头文件,该头文件存在与你JDK的include文件夹中,但是该jni.h还引用其他文件,为了保险起见,需要将jdk中的include文件夹和该文件夹下的window32文件夹加入到当前的项目中,具体的操作为,在vs2019右侧的项目目录中点击项目名,并鼠标右键,选择“属性”,弹出如下对话框:

8af94c37d3e870c092b14317d516d10c.png

在包含目录中添加jdk相应的路径,如下图所示:

97acbbf175fd1168109f99e685bc5d56.png

然后进行重新编译即可。

2、在进行java调用时,出现Can't load IA 32-bit .dll on a AMD 64-bit platform错误

这是由于你生成的dll是32位的,然而Java的jdk是64位的导致的。解决方法,有两种方法,一种是更换jdk版本变更成32位的;另一种采用X64重新对dll进行编译,其具体的操作过程为:1、在vs2019顶部选择“生成-》配置管理器”,如下图所示:

ec817b00160dbb55042ebd5362fb35d0.png

在上图中“平台”选项中选择正确的平台,然后进行重新编译,即可解决该类问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值