Java和C++都是我所热爱的语言,但是众所周知,C++学习是一件长期艰苦的事情,C++适用于需要“硬件级别”操作的软件,其语法复杂,内存也需要我们程序员来自动管理等,而Java向程序员隐藏了指针,相对于C++来说更加安全,而且Java具有内置的垃圾回收机制和多线程等机制,而且Java网络编程也是对程序员来说比C++要友好,从而Java也是深受许多程序员的喜爱。
下面一段话,送给还在纠结选C++ or Java 的同学们:
总体来说,C++几乎可以实现任何功能,但除非拥有明显的特殊理由,否则我不会将C++作为首选。Java则是一切都刚刚好——虽然并非最佳,但确实完全足够。
以下是举例说明:
用Java写好一个类声明(或者说函数),其具体功能是实现两个整数的加减法。
最终这个工程会产生Math.jar和Math.dll以供后面的Project2中的Java程序调用。
前提条件:
Projecte2的目标:
是一个Java程序,用于测试Project1中产生的Math.jar和Math.dll。
题外话:需要说明的是,在实验过程中我并没有使用任何的集成开发环境,因为集成开发环境往往会让我不知所措,it always make me confused. 所以我完全是使用命令行进行实验。另外,请读者关注引用框中的内容,因为那往往是容易出错的地方。
其中,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);
}
首先进入到Math.java目录中(后续操作都在该目录中进行),然后执行如下编译命令
javac -d . Math.java
- javac的参数 -d <目录> 用于指定放置生成的类文件的位置
- 使用-d选项,编译器会自动给我们生成对应包名的目录结构
- . 表示当前目录
效果如下图:
- javah 操作的一定是class文件
- 注意类名要写为类的全名
具体命令为:
javah -cp . com.cholen.math.Math
执行完成后,会自动生成一个c/c++头文件,如下图:
请不要修改这个头文件,这个头文件的内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* 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
就是包含以下刚刚生成的头文件,然后把头文件中声明的函数拷贝过来,并添加实现体。
其内容如下:
#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’错误
具体编译命令如下:
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文件,注意,我们此时的文件结构如下图:
- 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文件了。
其中,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
具体编译命令为:
javac -cp .;./Math.jar -d . Main.java
- -cp <路径> 指定查找用户类文件和注释处理程序的位置
-cp 后面接的是一个(或多个)第三方jar包的路径,多个路径之间用英文分号;隔开,它告诉Java编译器除了jdk提供的标准库外,你还应该去这些地方找所需要的类。 (后面一步的java命令相同)
经过编译,此时,我们的文件结构如下图:
具体命令为:
java -cp .;./Math.jar org.ch.Main
- 注意为类的全名,且不带.class后缀名
如果上述步骤都正确的话,你应该会得到正确的结果,如下图:
至此,我们便完成了:
原网址: 访问
创建于: 2023-10-23 09:58:16
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论