使用Java调用C/C++

article/2025/10/17 0:16:35

文章目录

    • 前言
    • JNI概述
    • 例子
        • 编写Java代码
        • 编译生成的class文件:JNITest.class
        • 在命令行下使用javah生成C/C++头文件。在工程的bin目录下输入以下命令:
        • 实现C++代码。在VS2008中创建一个Win32 project,类型为DLL。
        • 构建C++项目
        • 将dll文件复制到Java工程的bin目录下

前言

我们知道Java是一种平台无关性的语言,平台对于上层的java代码来说是透明的,所以在多数时间我们是不需要调用本地方法,但是假如你遇到了以下情况,你可能就需要使用Java调用本地方法了:

1、你的Java代码需要得到一个文件的属性。但是你找遍了JDK帮助文档也找不到相关的API。
2、在本地还有一个别的系统,不过它不是Java语言实现的,这个时候你需要把两套系统整合到一起。
3、你的Java代码中需要用到某种算法,不过算法是用C实现并封装在动态链接库文件(DLL)当中的。

对于上述的三种情况,如果没有JNI的话,那就会变得异常棘手了。JNI其实是Java Native Interface的简称,也就是java本地接口。它提供了若干的API实现了和Java和其他语言的通信(主要是C&C++)。
在Java中有一些native方法,这些方法只有方法签名但是没有方法体。其实这些naive方法就是我们说的 java native interface。它提供了一个调用(invoke)的接口,然后用C或者C++去实现。

JNI概述

JVM封装了各种操作系统实际的差异性的同时,提供了JNI技术,它是一种双向的接口,使得开发者可以通过Java代码调用到各种native的库,反之亦然。所以JNI(Java Native Interface)能作为Java语言的一部分,她能够作为粘合剂将Java应用和其他本地应用(C/C++,Delphi)集合在一起。
在这里插入图片描述
作为一个双向的接口,JNI能支持两种native代码:native libraries 和native applications。

你能使用JNI去写一些native methods去允许Java Applications能呼叫native libraries中的函数,native methods的具体  
实现是可能C,C++或者Delphi。
JNI也支持嵌入一个JVM实现到一个本地应用程序中去,去执行那些用Java语言编写的的模块.比如,一个C++编写的  
浏览器利用内嵌的JVM去执行下载到本地的applet。

实现步骤:

1、完成Java代码,编写好Java调用类。
2、编译你的Java类。
3、用javah生成编译好的class文件对应的C/C++ 函数的头文件。
4、实现头文件中的函数原型,编写native代码。
5、将native代码编译打包成DLL库(win32)或共享库(Linux)。
6、将你的Java代码跑起来

例子

编写Java代码

注意

  1. 调用本地代码的java方法,要设置成native的。
  2. 要使用System的LoadLibrary方法去加载包含本地方法实现的库。
    Java代码
package eric.test;  
public class JNITest {           static {  System.loadLibrary("JNITest");  }           public static native void sayHelloWorld(String msg);           public static void main(String[] args) {  sayHelloWorld("Hello, world");  }  
}  

编译生成的class文件:JNITest.class

在命令行下使用javah生成C/C++头文件。在工程的bin目录下输入以下命令:

cmd代码

javah -classpath . -jni eric.test.JNITest

将生成头文件eric_test_JNITest.h,内容如下:
app代码

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

注意,在执行javah的时候,要输入完整的包名和类名。否则在以后的测试调用过程中会发生java.lang.UnsatisfiedLinkError这个异常。

实现C++代码。在VS2008中创建一个Win32 project,类型为DLL。

将刚才生成的头文件eric_test_JNITest.h拷到工程目录下,并且在项目中导入到Header Files里面。打开StdAfx.h文件,在最后面添加:
cpp代码

#include "jni.h"  
#include "eric_test_JNITest.h" 

打开JNITest.cpp文件,在其中添加实现代码。函数名为头文件中定义的函数声明。
app代码

#include <iostream>  
using namespace std;  JNIEXPORT void JNICALL Java_eric_test_JNITest_sayHelloWorld  (JNIEnv* env, jclass method, jstring param)  
{  const char* pt = env->GetStringUTFChars(param, 0);   cout << pt << " called by Java Native Interface" << endl;   
}

其中,GetStringUTFChars是jre中提供的jni方法,用来得到java string的字符串。

构建C++项目

会出现"Cannot open include file: ‘jni.h’: No such file or directory"的错误,解决方法是将以下文件拷贝到C++工程目录下

%JAVA_HOME%\include\jni.h
%JAVA_HOME%\include\win32\jni_md.h

同时将头文件eric_test_JNITest.h中的 #include <jni.h> 改为
cpp代码

#include "jni.h"

然后重新build,将在debug目录下生成JNITest.dll文件。

将dll文件复制到Java工程的bin目录下

(这个位置十分重要,否则会出现not found的异常),并运行程序
cmd代码

java eric.test.JNITest

将输出结果"Hello, world called by Java Native Interface"。


http://chatgpt.dhexx.cn/article/m2S2FTm7.shtml

相关文章

java调用c/c++

最近项目想将比较重要的配置文件加密、综合考虑后决定用java jni实现&#xff0c;步骤如下 1.定义java本地接口 package com.msg.jni;public class JniMsg {static {try {String os System.getProperty("os.name").toLowerCase();String path "F:/opt/"…

C/C++如何调用Java

前言 简单介绍C/C如何调用Java&#xff0c;内容适合未接触过此类工程的朋友作为上手参考。 一、编译环境 1. 64位的win10系统 2. JDK&#xff1a;jdk-8u181-windows-x64.exe 3. IDE VS2017 二、调用步骤及Java虚拟机使用方法 一般步骤&#xff1a; 编写Java代码, 并编译…

java调用C

文章目录 idea创建一个java类通过命令生成.h文件vs2015创建dll项目修改dll项目的属性补充dll项目的头文件和源文件导入文件源文件的制作 生成dll文件idea导入dll文件idea使用函数 这个确实卡了我一段时间。 先说说必要性吧。 java无法处理的操作&#xff08;指向地址&#xff…

Java调用c/c++(JNI)最详细步骤

一、JNI(Java Native Interface)的作用就是Java通过JNI调用其他语言的函数(或方法)&#xff08;主要是C&C&#xff09;。 二、准备 1. java8系列jdk&#xff0c;有很多版本&#xff0c;任选一个即可&#xff0c;如jdk1.8.0.231。安装好&#xff0c;配置好环境。 2. vs20…

使用java调用C语言程序教程

1.idea创建一个java类 严格来说&#xff0c;核心步骤并不是创建一个java类&#xff0c;而是创建一个方法&#xff0c;那个方法要被native修饰&#xff0c;这才是关键。 接着在TestNativeCode类当中声明我们的本地方法&#xff1a; package com.wwj.nativecode; public class T…

linux中文语言包下载地址,centos中文语言包-官方版-centos中文语言包fonts-chinese-3.02-12.el5.noarch.rpm-独木成林...

centos中文语言包 fonts-chinese-3.02-12.el5.noarch.rpm&#xff0c;直接在目录下运行&#xff1a; rpm -ivh fonts-chinese-3.02-12.el5.noarch.rpm linux中文文件名乱码的解决办法(安装中文支持包) 由于安装英文版的系统不支持中文&#xff0c;出现中文文件名乱码。 下面操作…

Linux-centos安装MySQL8.0.22连接驱动文件mysql-connector-java-8.0.22-1.el7.noarch.rpm

目录 1、下载地址 2、选择版本 3、安装驱动 1、下载地址 https://downloads.mysql.com/archives/c-j/ 2、选择版本 选择对应的版本&#xff0c;这里系统选择Redhat系列Linux7&#xff0c;驱动版本选择8.0.22&#xff0c;点击download下载到本地再上传至服务器安装。 也可…

Mysql-MHA 安装过程中遇到的问题 :报错rpm -ivh mha4mysql- manager- 0.56-0.el6.noarch.rpm错误:依赖检测失败:

rpm -ivh mha4mysql- manager- 0.56-0.el6.noarch.rpm 错误&#xff1a;依赖检测失败&#xff1a; perl(Config::Tiny) 被 mha4mysql-manager-0.56-0.el6.noarch 需要 perl(Log::Dispatch) 被 mha4mysql-manager-0.56-0.el6.noarch 需要 perl(Log::Dispatch::File) 被 mha4mysq…

Linux下载并安装rabbitmq-server-3.6.5-1.noarch.rpm

目录 1.安装rabbitmq所需要的依赖包 2.下载安装包 3.安装服务命令 4.修改配置 5.启动rabbitmq 6.rabbitmq控制台安装 7.访问你的虚拟机 ip:15627 会出现下面的页面 用户名和密码都是 guest 8.常用命令 1.安装rabbitmq所需要的依赖包 yum install build-essential o…

centos rpm安装mysql时依赖检测失败:mysql57-community-release 与 mysql80-community-release-el8-3.noarch 冲突

1.出现以上报错&#xff0c;说明MySQL安装版本冲突 首先卸载原来的MySQL rpm -qa |grep mysql //搜索安装的MySQL包rpm -e --nodeps 搜索出来的包名 //卸载示例&#xff1a; [rootcentos8s ~]# rpm -qa |grep mysql mysql57-community-release-el7-11.noarch [rootcent…

yum 安装daemonize 错误:依赖检测失败: daemonize 被 jenkins-2.303.1-1.1.noarch 需要

错误&#xff1a;依赖检测失败&#xff1a; daemonize 被 jenkins-2.303.1-1.1.noarch 需要 安装 epel-release yum -y install epel-release安装 daemonize yum -y install daemonize结果&#xff1a;

php代码解决乱码问题

在用php的passthru函数的时候&#xff0c;然后出现了乱码的情况 代码&#xff1a; <?php echo passthru("ipconfig"); ?> 解决方法&#xff1a; 在原来的代码前面加 header("content-type:text/html;charsetgbk2312"); charset——后面是修改…

PHP-MySQL乱码[?]问题处理

PHP-MySQL乱码[?]问题处理 PHP-MySQL乱码[?]问题处理问题展示原因分析查看数据库编码格式WindowsLINUX 解决方案1、修改MySQL配置文件2、修改php连接数据库的编码格式。 修改后结果展示 PHP-MySQL乱码[?]问题处理 问题展示 php执行sql语句返回结果为’???’ 原因分析…

PHP文件乱码解决

1.查看项目的编码格式是不是UTF-8 2.在页面的开始处加入下面代码 <?php header("content-type:text/html;charsetutf-8"); //设置编码 ?>3.如果是html和PHP语言混合的PHP文件&#xff0c;还需要<head>标签下&#xff0c;加如下代码&#xff1a; <…

php如何解决中文乱码问题?

首先 乱码为什么会发生&#xff1f; 乱码的发生大致有2种原因&#xff0c;一种是编码(charset) 设置错误&#xff0c;导致浏览器以错误的编码来解析&#xff1b;另一种是文件被以错误的编码打开&#xff0c;然后保存&#xff0c;比如一个文本文件原先是GB2312 编码的&#xff…

php页面上显示中文乱码怎么解决,php输出中文乱码问题怎么解决?,php页面中文显示乱码...

php输出中文乱码问题怎么解决&#xff1f;怎么解决PHP输出中汉字乱码问题&#xff1f;&#xff0c;解决方案&#xff1a;1。对于HTML和PHP混合的页面&#xff0c;应该使用元标签或者header()函数来统一页面编码&#xff1b;2.对于纯PHP的静态页面&#xff0c;使用header()函数将…

解决html、php中文乱码问题

我们将乱码情况分为以下几种&#xff0c;有需要的可以对照下面的几种情况有针对性的解决乱码问题 第一种&#xff1a;解决HTML中中文乱码问题方法 如果你的HTML文件文件出现了乱码问题&#xff0c;那么你可以在head标签里面加入UTF8编码(国际化编码)&#xff1a;UTF-8是没有国…

解决 PHP 输出中文乱码的问题

本文由荒原之梦原创&#xff0c;原文链接&#xff1a;http://zhaokaifeng.com/?p1340 解决 PHP 输出中文乱码的问题 问题描述 今天给导航狗(https://daohanggou.cn/)的 PHP 程序和数据库文件迁移了服务器, 但是迁移到新的服务器上之后 PHP 输出的中文和 PHP 输出的从 MySQL…

原创:PHP乱码怎么办?五种方法彻底解决PHP乱码问题

对于刚接触PHP的新手来说&#xff0c;乱码可能会让你边临崩溃&#xff0c;但是你要习惯&#xff0c;既然想学好PHP&#xff0c;乱码是家常便饭&#xff0c;不管是老鸟还是新手&#xff0c;都会遇到乱码的问题&#xff0c;下面是我总结的几个常见并且有效的解决方法&#xff1a;…

win7 装MacOS虚拟机做iOS开发

1. 下载安装Vmware Player 2. 下载MacOS10.6 Image http://www.verycd.com/topics/2897839/ [Mac.OS.X.操作系统].Mac.OS.X.Lion.10.7.VMware.Pre-Installed.Image.zip 详情 转载于:https://www.cnblogs.com/technical/archive/2012/04/13/2445417.html