Java与C++混合编程之Java调用C++ 您所在的位置:网站首页 java跟c Java与C++混合编程之Java调用C++

Java与C++混合编程之Java调用C++

2023-10-10 13:58| 来源: 网络整理| 查看: 265

零、题外话

Java和C++都是我所热爱的语言,但是众所周知,C++学习是一件长期艰苦的事情,C++适用于需要“硬件级别”操作的软件,其语法复杂,内存也需要我们程序员来自动管理等,而Java向程序员隐藏了指针,相对于C++来说更加安全,而且Java具有内置的垃圾回收机制和多线程等机制,而且Java网络编程也是对程序员来说比C++要友好,从而Java也是深受许多程序员的喜爱。

下面一段话,送给还在纠结选C++ or Java 的同学们:

总体来说,C++几乎可以实现任何功能,但除非拥有明显的特殊理由,否则我不会将C++作为首选。Java则是一切都刚刚好——虽然并非最佳,但确实完全足够。

在这里插入图片描述

一、目标 使用Java声明类方法而将其实现交给C++来做(譬如要求实时性非常强的一些操作就交给C++来做);向别的客户(Java程序)提供jar文件和动态库文件(当然最好提供一组文档接口,告诉你的客户应该如何调用你写的模块),从而实现隐藏你的源代码;此时,jar文件中是一些class的集合,但是仅仅只有声明,其真正的实现是在动态库中。

以下是举例说明:

1、Project1

用Java写好一个类声明(或者说函数),其具体功能是实现两个整数的加减法。 最终这个工程会产生Math.jar和Math.dll以供后面的Project2中的Java程序调用。 在这里插入图片描述

2、Project2

前提条件:

将Project1中产生的Math.jar和Math.dll拷贝到当前工程中来

Projecte2的目标: 是一个Java程序,用于测试Project1中产生的Math.jar和Math.dll。 在这里插入图片描述

二、具体实现

题外话:需要说明的是,在实验过程中我并没有使用任何的集成开发环境,因为集成开发环境往往会让我不知所措,it always make me confused. 所以我完全是使用命令行进行实验。另外,请读者关注引用框中的内容,因为那往往是容易出错的地方。

1、Project1 1.1 创建Project1文件夹,并在其中创建一个Math.java文件

其中,Math.java中的文件内容如下(注意使用native关键字):

package com.cholen.math; public class Math{ public static native int add(int x,int y); public static native int sub(int x,int y); } 1.2 使用javac编译该Java文件

首先进入到Math.java目录中(后续操作都在该目录中进行),然后执行如下编译命令

javac -d . Math.java javac的参数 -d 用于指定放置生成的类文件的位置使用-d选项,编译器会自动给我们生成对应包名的目录结构 . 表示当前目录

效果如下图: 在这里插入图片描述

1.3 使用javah命令生成对应的c/c++头文件 javah 操作的一定是class文件注意类名要写为类的全名

具体命令为:

javah -cp . com.cholen.math.Math

执行完成后,会自动生成一个c/c++头文件,如下图: 在这里插入图片描述 请不要修改这个头文件,这个头文件的内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class com_cholen_math_Math */ #ifndef _Included_com_cholen_math_Math #define _Included_com_cholen_math_Math #ifdef __cplusplus extern "C" { #endif /* * Class: com_cholen_math_Math * Method: add * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_cholen_math_Math_add (JNIEnv *, jclass, jint, jint); /* * Class: com_cholen_math_Math * Method: sub * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_cholen_math_Math_sub (JNIEnv *, jclass, jint, jint); #ifdef __cplusplus } #endif #endif 1.4 在当前文件夹下建立一个com_cholen_math_Math.cpp文件

就是包含以下刚刚生成的头文件,然后把头文件中声明的函数拷贝过来,并添加实现体。 其内容如下:

#include "com_cholen_math_Math.h" /* * Class: com_cholen_math_Math * Method: add * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_cholen_math_Math_add (JNIEnv *, jclass, jint x, jint y) { return x + y; } /* * Class: com_cholen_math_Math * Method: sub * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_cholen_math_Math_sub (JNIEnv *, jclass, jint x, jint y){ return x -y; } int main(int argc, const char* argv[]){ } 请务必写上一个空的main函数,否则在后面一步编译时会产生 undefined reference to `WinMain’错误 1.5 使用g++命令进行编译

具体编译命令如下:

g++ -ID:\SDK\Java\jdk1.8.0_231\include -ID:\SDK\Java\jdk1.8.0_231\include\win32 com_cholen_math_Math.cpp -o Math.dll g++ -I参数后面接的是一个路径,-I参数告诉g++去那个路径下寻找它所需要的头文件g++ -I参数与路径名之间请不要添加任何空格g++ -o 参数后面接的是你想让g++生成的文件名请不要照抄上述命令,请务必包含你自己电脑jdk下的那两个路径

经过编译,会在当前目录下生成Math.dll文件,注意,我们此时的文件结构如下图: 在这里插入图片描述

1.6 使用jar命令生成jar文件 jar 命令作用的对象是class文件,请一定要带上.class后缀名,请一定要写类的路径,不要写类的全名jar 命令类似于Linux中的tar命令,读者可以自行学习jar 命令相当于把一大堆class文件打了一个包jar -c 参数 创建新档案jar -v 参数 在标准输出中生成详细输出jar -f 参数 指定档案文件名

具体的命令为:

jar -cvf Math.jar ./com/cholen/math/Math.class后面那一部分千万不可写成com.cholen.math.Math.class

经过打包,会在当前目录下生成一个Math.jar包,注意,我们此时的文件结构如下图: 在这里插入图片描述 至此,我们的Project1工程算是完成了,剩下的便是向别人提供我们写好的Math.jar和Math.dll文件了。

2、Project2 2.1 创建Project1文件夹,并在其中创建一个Main.java文件,并将Project1中的Math.jar和Math.dll文件拷贝进来

其中,Main.java的内容如下:

package org.ch; public class Main{ public static void main(String[] args){ int a = 10; int b = 20; int c = com.cholen.math.Math.add(a,b); int d = com.cholen.math.Math.sub(a,b); System.out.println("c ="+c); System.out.println("d ="+d); } static { System.loadLibrary("Math"); } } System.loadLibrary()用来加载某一个动态库文件注意System.loadLibrary()的参数为Math,不是Math.dll 2.1 使用javac命令编译Main.java文件

具体编译命令为:

javac -cp .;./Math.jar -d . Main.java -cp 指定查找用户类文件和注释处理程序的位置 -cp 后面接的是一个(或多个)第三方jar包的路径,多个路径之间用英文分号;隔开,它告诉Java编译器除了jdk提供的标准库外,你还应该去这些地方找所需要的类。 (后面一步的java命令相同)

经过编译,此时,我们的文件结构如下图: 在这里插入图片描述

2.3 使用java命令运行

具体命令为:

java -cp .;./Math.jar org.ch.Main 注意为类的全名,且不带.class后缀名

如果上述步骤都正确的话,你应该会得到正确的结果,如下图: 在这里插入图片描述

至此,我们便完成了:

一方面,我们提供了由Java声明并由C/C++实现的类方法,从而生成了动态库文件,并将编译好的class文件打包成一个jar文件,将动态库文件和jar文件发给别人以供别人使用,与此同时,最好写一份文档说明你所提供的接口(这个功能由javadoc命令可以完成,读者可以自行学习)。另一方面,我们学习了如何在我们的Java程序中如何使用第三方提供的jar包和动态库文件。


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有