java调用C

本文详细介绍了如何在Java中调用C语言编写的DLL函数,包括创建Java类,使用javah生成.h文件,用VS2015创建DLL项目,修改属性,编写源文件,生成DLL,导入IDEA并使用函数。涉及的关键步骤包括native方法定义,头文件和源文件的制作,以及DLL的加载与调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


这个确实卡了我一段时间。

先说说必要性吧。

  1. java无法处理的操作(指向地址)
  2. 用其他语言会方便很多。
  3. 因为其他语言项目很成熟了,不好推掉重来。而我只习惯用java的话,便可以继续使用java工作,只是要调用人家写好的代码。

java调用除了C语言的其他语言都较容易,甚至可以靠导包来完成转换,唯独C难搞,盲猜是因为其可访问物理地址的缘故。

那么java如何调用c?

步骤如下:

1. idea创建一个java类
2. 通过命令生成.h文件
3. vs2015创建dll项目
4. 修改dll项目的属性
5. 补充dll项目的头文件和源文件
6. 生成dll文件
7. idea导入dll文件
8. idea使用函数

idea创建一个java类

严格来说,核心步骤并不是创建一个java类,而是创建一个方法,那个方法要被native修饰,这才是关键。

package cn.hsl.search;

public class javaConnectC {
    public native void hsl(String a,char b,int c);
}

通过命令生成.h文件

操作步骤为:

  1. 找到第一步所创建的java文件
  2. 打开cmd
  3. 输入命令 javac -h ./ [java文件位置]

然后就会在cmd的当前路径下生成一个.h文件,我们把那个.h文件剪切到我们的临时目录里。结束了就可以把目录干掉

那个.h文件名就是我们的包名+类名

例如我的包名加 cn.hsl.search

类名叫javaConnectC

然后.h的文件名就是:cn_hsl_search_javaConnectC

其里面的方法在文件名的基础上,在最前面还要加个Java,最后面还要加上方法名

即:Java_cn_hsl_search_javaConnectC_hsl

vs2015创建dll项目

其实vs2019应该也行的,但我那时候不懂…

新建一个dll项目

把dll项目下的头文件和源文件目录下的文件都可以删了

我命名的dll项目名为javaConnectC,放的目录为桌面/JCC

修改dll项目的属性

右键单机dll项目,找到 属性选项(其实左键单机dll项目,然后alt+enter也可以直接打开)。

会弹出一个对话框,然后找到 配置属性 - VC++ 目录

然后添加VC++ 目录下的包含目录的值,点击包含目录的值,单击最右边的下拉按钮,选择《编辑》

然后选择本地jdk目录下include文件夹,我的是 D:/jdk-14.0.1/include

和选择jdk目录下的include/win32文件夹,我的是 D:/jdk-14.0.1/include/win32

感到难找的话,其实也可以全盘搜索jni.h文件,包含那个文件的jdk就是我们所需要的jdk
在这里插入图片描述

以上是VC++ 目录的修改

然后是预编译头的修改

还是那个属性对话框

找到 配置属性 - C/C++ - 预编译头

在预编译头那里找到预编译头的值,点开最右边的下拉按钮,选择不使用预编译头

在这里插入图片描述

然后就结束了。

补充dll项目的头文件和源文件

导入文件

找到通过命令生成的.h文件,我的是直接放在桌面的。

然后将.h文件复制到dll项目的目录下。即,将 临时目录/javaConnectC.h 复制到 桌面/JCC/javaConnectC/javaConnectC 目录下,反正就是放在原来存放dll项目头文件的位置。

我们再创建一个.c/.cpp文件,如果已经有了,可以也放在原来dll项目的头文件的位置,即桌面/JCC/javaConnectC/javaConnectC 下。

然后去vs的dll项目那里,在头文件和源文件目录那里进行导入头、源文件。

源文件的制作

我的源文件名叫javaConnectC.c文件,其实cpp也行,而且也不必跟.h文件同名

只是对源文件内容有要求,必须导入那个生成的.h文件,即javaConnectC.h文件

然后方法的话,复制.h文件下的 JNIEXPORT所修饰的那段方法。

复制到.c文件那里,然后给方法的形参加上字段。

然后把那个方法当作是main方法,就可以当作是C文件去敲了。

至于传值情况下,貌似传值若是char类的话,便不可用printf去打印char字符。其他String和int都可以

头文件代码:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class cn_hsl_search_javaConnectC */

#ifndef _Included_cn_hsl_search_javaConnectC
#define _Included_cn_hsl_search_javaConnectC
#ifdef __cplusplus
extern "C" {
#endif
	/*
	* Class:     cn_hsl_search_javaConnectC
	* Method:    hsl
	* Signature: (Ljava/lang/String;CI)V
	*/
	JNIEXPORT void JNICALL Java_cn_hsl_search_javaConnectC_hsl
		(JNIEnv *, jobject, jstring, jchar, jint);

#ifdef __cplusplus
}
#endif
#endif

源文件代码:

#include"cn_hsl_search_javaConnectC.h"
#include"stdio.h"
JNIEXPORT void JNICALL Java_cn_hsl_search_javaConnectC_hsl
(JNIEnv * env, jobject obj, jstring str, jchar chr, jint jin) {
	putchar(chr);
	printf("this is int: %d\n",jin);
	printf("this is string: %s\n", str);
}

生成dll文件

接下来直接按 生成 -> 生成xxx项目 即可

在这里插入图片描述

idea导入dll文件

将dll文件放到idea的lib的位置
的位置:找个跑的通的代码,加个静态代码 static{ System.loadLibrary(“aaa”) },然后就会报错,提示我们[lib的位置]上没有这个aaa.dll

其实也可以自己声明一个lib的位置,但我不会做。

idea使用函数

随便找个跑的通的位置,调用第一步创建的那个java类

然后在类下面搞个静态代码块,来提前加载lib

static{
	System.loadLibrary("javaConnectC");
}

然后就可以在这个类里面直接调用java的那个方法。

package cn.hsl.search;

import cn.hsl.dao.mapper.GoodsMapper;
import cn.hsl.dao.pojo.Goods;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class SearchApplicationTest {
    
    static {
        System.loadLibrary("javaConnectC");
    }
    @Test
    void ww(){
        javaConnectC javaConnectC = new javaConnectC();
        javaConnectC.hsl("HSL",'i',1);
    }
}

参考了两个作者的步骤

参考 PacosonSWJTU 从创建java类到创建.h文件

参考 你是小KS 怎么将.h文件直接制作成dll

最后我自己摸索了怎么在idea导入dll

至于使用嘛,也是参考了 PacosonSWJTU

PacosonSWJTU 博客网址:https://blog.youkuaiyun.com/PacosonSWJTU/article/details/50618022

PacosonSWJTU 博客标题:本地方法(JNI)——从java 程序中调用C函数

你是小KS 博客网址:https://blog.youkuaiyun.com/weixin_45492007/article/details/123018918

你是小KS 博客标题:Java:使用javah生成.h文件并完成dll调用

谢幕

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值