C 调用 Java 方法

article/2025/10/16 22:14:00

文章目录

      • 1 Java 代码
      • 2 C 代码
      • 3 总结
        • 3.1 获取参数
        • 3.2 调用方法

在这里插入图片描述

1 Java 代码

JNI 代码

package com.karashok;import java.util.UUID;public class JNIDemo {/*** 获取静态方法返回值*/public static native String sayHello();/*** 获取方法返回值*/public native String sayWorld();/*** 修改属性 s*/public native void setS();/*** 修改静态属性 ss* @return*/public native static void setSs();private String s = "qwer";private static String ss = "asdf";public static String getSs() {return ss;}public String getS() {return s;}private long getTime() {return System.currentTimeMillis();}private static String getUUid() {return UUID.randomUUID().toString();}
}

main 代码

package com.karashok;public class Main {static {System.load("libDemo.dylib");}public static void main(String[] args) {JNIDemo demo = new JNIDemo();System.out.println("----- 获取静态方法返回值 -----");System.out.println("静态方法返回值: " + JNIDemo.sayHello());System.out.println("----- 获取方法返回值 -----");System.out.println("方法返回值: " + demo.sayWorld());System.out.println("----- 修改静态属性 -----");System.out.println("静态属性修改前: " + JNIDemo.getSs());JNIDemo.setSs();System.out.println("静态属性修改后: " + JNIDemo.getSs());System.out.println("----- 修改属性 -----");System.out.println("属性修改前: " + demo.getS());demo.setS();System.out.println("属性修改后: " + demo.getS());}
}

2 C 代码

需要将 jni.hjni_md.h 两个头文件放到包中。

头文件代码

#include "jni.h"
#include <string.h>#ifndef DEMO_LIBRARY_H
#define DEMO_LIBRARY_H/** Class:     com_karashok_JNIDemo* Method:    sayHello* Signature: ()Ljava/lang/String;*/
JNIEXPORT jstring JNICALL Java_com_karashok_JNIDemo_sayHello
(JNIEnv *, jclass);/** Class:     com_karashok_JNIDemo* Method:    sayWorld* Signature: ()Ljava/lang/String;*/
JNIEXPORT jstring JNICALL Java_com_karashok_JNIDemo_sayWorld
(JNIEnv *, jobject);/** Class:     com_karashok_JNIDemo* Method:    setS* Signature: ()Ljava/lang/String;*/
JNIEXPORT void JNICALL Java_com_karashok_JNIDemo_setS
(JNIEnv *, jobject);/** Class:     com_karashok_JNIDemo* Method:    setSs* Signature: ()Ljava/lang/String;*/
JNIEXPORT void JNICALL Java_com_karashok_JNIDemo_setSs
(JNIEnv *, jclass);#endif //DEMO_LIBRARY_H

代码

#include "library.h"JNIEXPORT jstring JNICALL Java_com_karashok_JNIDemo_sayHello(JNIEnv *jniEnv, jclass jcls) {jmethodID mid = (*jniEnv)->GetStaticMethodID(jniEnv,jcls,"getUUid","()Ljava/lang/String;");jstring jstr = (*jniEnv)->CallStaticObjectMethod(jniEnv,jcls,mid);char *str = (*jniEnv)->GetStringUTFChars(jniEnv,jstr,JNI_FALSE);printf("UUID is: %s\n",str);return (*jniEnv)->NewStringUTF(jniEnv,"Hello ");
}JNIEXPORT jstring JNICALL Java_com_karashok_JNIDemo_sayWorld(JNIEnv *jniEnv, jobject jobj) {jclass jcls = (*jniEnv)->GetObjectClass(jniEnv,jobj);jmethodID mid = (*jniEnv)->GetMethodID(jniEnv,jcls,"getTime","()J");jlong jl = (*jniEnv)->CallLongMethod(jniEnv,jobj,mid);printf("Time is: %ld\n",jl);return (*jniEnv)->NewStringUTF(jniEnv,"World!\n");
}JNIEXPORT void JNICALL Java_com_karashok_JNIDemo_setS(JNIEnv *jniEnv, jobject jobj) {jclass jcls = (*jniEnv)->GetObjectClass(jniEnv,jobj);jfieldID fid = (*jniEnv)->GetFieldID(jniEnv,jcls,"s","Ljava/lang/String;");jstring jstr = (*jniEnv)->GetObjectField(jniEnv,jobj,fid);char *str = (*jniEnv)->GetStringUTFChars(jniEnv,jstr,JNI_FALSE);char newStr[20] = "Demo ";strcat(newStr,str);jstring newjstr = (*jniEnv)->NewStringUTF(jniEnv,newStr);(*jniEnv)->SetObjectField(jniEnv,jobj,fid,newjstr);}JNIEXPORT void JNICALL Java_com_karashok_JNIDemo_setSs(JNIEnv *jniEnv, jclass jcls) {jfieldID fid = (*jniEnv)->GetStaticFieldID(jniEnv,jcls,"ss","Ljava/lang/String;");jstring jstr = (*jniEnv)->GetStaticObjectField(jniEnv,jcls,fid);char *str = (*jniEnv)->GetStringUTFChars(jniEnv,jstr,JNI_FALSE);char newStr[20] = "Demo ";strcat(newStr,str);jstring newjstr = (*jniEnv)->NewStringUTF(jniEnv,newStr);(*jniEnv)->SetStaticObjectField(jniEnv,jcls,fid,newjstr);
}

3 总结

3.1 获取参数

  1. 获取 class 对象
  2. 获取属性的 fieldID
  3. 获取属性值
  4. 将属性值转化为 c 的值

3.2 调用方法

  1. 获取 class 对象
  2. 获取方法的 methodID
  3. 调用方法获取返回值
  4. 将返回值转化为 c 的值

注意: C 调用 Java 方法是不区分权限的,也就是说 public 的属性/方法和 private 的属性/方法是一样的。

获取方法签名:javap -s -p com.karashok.JNIDemo,一定要尽到相应 src 的根目录下而不是类的目录。


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

相关文章

java调用c/c++代码

JNI是Java Native Interface的英文缩写, 中文翻译为本地调用, 自从Java 1.1开始就成为了Java标准的一部分。 C/C是系统级的编程语言, 可以用来开发任何和系统相关的程序和类库, 但是Java本身编写底层的应用比较难实现, 使用JNI可以调用现有的本地库, 极大地灵活了Java的开发。…

java调用C++代码

首先我的参考博客如下&#xff1a; https://www.cnblogs.com/CLAYJJ/p/7725975.html https://www.cnblogs.com/xiaocainiao2hao/p/5619862.html https://www.cnblogs.com/langtianya/p/3470896.html 流程如下&#xff1a; 1.建立一个java文件&#xff0c;在这里我只写了一…

C语言调用Java JNI

最近项目中需要使用JNI&#xff0c;所以研究了一下&#xff0c;其中遇到过不少问题&#xff0c;总结一下&#xff0c;让遇到同样问题的人可以得到解决。 在C/C中调用Java的方法一般分为五个步骤&#xff1a;初始化虚拟机、获取类、获取类的方法、创建类对象、调用方法和退出虚…

java程序如何调用C++代码

看到java多线程中的Thread.isAlive()的类型为native&#xff0c;进一步去联想native方法什么时候用呢&#xff1f;自己能不能编写native方法&#xff1f; 经网上查资料&#xff1a; java中native修饰符的含义为“a native method is a java method whose implementation is p…

Java调用C++程序实现方法

Java调用C程序实现方法(1) 这篇博文是自己在学习过程中&#xff0c;踩了很多坑之后&#xff0c;为了避免广大热爱编程的盆友再像我这样浪费太多时间&#xff0c;索性将自己的实现方法总结出来&#xff0c;以供大家参考。程序最终实现的是Hello World效果&#xff0c;话不多说&…

从 C/C++ 程序调用 Java 代码

JNI允许您从本机代码内调用 Java 类方法。 要做到这一点&#xff0c;通常必须使用 Invocation API 在本机代码内创建和初始化一个 JVM。 下列是您可能决定从 C/C 代码调用Java 代码的典型情况&#xff1a; 1.希望实现的这部分代码是平台无关的&#xff0c;它将用于跨多种平台…

使用Java调用C/C++

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

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语句返回结果为’???’ 原因分析…