用VSCode创建并在Java中通过JNA调用C动态链接库的方法
前言
我之前说过我在疯狂的学Java,前几天和朋友谈论到Java跨语言的事情
所以就上网搜了一下,发现资料很乱,所以自己整理了一番
总而言之,可用,但是可能会有问题
工具与环境
- Java 15
- Maven
- JNA
- VS Code
- IDEA
- MinGW-GCC
- Windows 10
构建一个C程序
要求
- 一个.c文件,存放你的自定义函数
- 一个.h文件,告诉别人你的程序里面有哪些自定义函数
编写libQYun_CAPI.c
这里我们用人人都会 的Hello World来举例
#include <stdio.h>
#include <libQYun_CAPI.h>
LIBQYun_CAPI void hello () // 你也可以不加LIBQYun_CAPI,这样编译器会报一个警告
{
char s[] = "Hello World";
printf("%s\n", s);
}
//Written by Aloento.
编写libQYun_CAPI.h
.h 文件里面应该包含你在 .c文件中需要暴露给用户的所有函数
#pragma once
#ifdef LIBQYun_EXPORTS
#define LIBQYun_CAPI __declspec(dllexport)
#else
#define LIBQYun_CAPI __declspec(dllimport)
#endif
LIBQYun_CAPI void hello ();
//Written by Aloento.
你的文件编码最好是UTF-8,这样如果你输中文也不会乱码
用VSCode把C程序编译为DLL
配置
在launch.json的"configurations"中插入以下代码
{
"name": "CLib-Windows",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/Test.exe",
"cwd": "${workspaceFolder}",
"preLaunchTask": "CDLL-Windows",
},
在task.json的"tasks"中插入以下代码
{
"type": "shell",
"label": "CDLL-Windows",
"command": "gcc",
"args": [
"-ggdb3",
"-shared",
"-Og",
"${file}",
"-o",
"${fileDirname}/libQYun_CAPI.dll",
"-I",
"${fileDirname}"
],
"problemMatcher": [
"$gcc"
],
"group": "build"
},
当然,DLL文件是没法直接运行的,所以"program"你就随便填
我们只要得到编译通过的消息就足够了
按F5,或者在运行选项卡中选择配置文件,并且编译
如果顺利,我们会得到libQYun_CAPI.dll文件
在Java中调用DLL
创建一个Maven项目并配置
Maven怎么用不是这篇文章要讨论的地方
多说一句,dll和你的JDK必须是同一个平台的
也就是说,x86就都得是x86,x64都得是x64
否则会报错,当然,CPU架构也得一样
获取JNA依赖
在< dependencies >标签中插入以下代码
<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna-platform -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.6.0</version>
</dependency>
把libQYun_CAPI.dll复制到resources文件夹下
创建接口QYun.java
新建一个接口,内容如下
import com.sun.jna.Library;
import com.sun.jna.Native;
public interface QYun extends Library {
QYun CAPI = Native.load("libQYun_CAPI", QYun.class);
void hello ();
}
//Written by Aloento.
创建Java类Hello.java
新建一个类,内容如下
public class Hello {
public static void main(String[] args) {
QYun.CAPI.hello();
}
}
//Written by Aloento.
调试与运行
如果正常,你会在控制台中看到
Hello World
至此,大功告成
碎碎念
我不是很愿意用Visual Studio,因为太大了,对纯C也不太友好
而且还会生成一大堆用不上的文件
当然,如果你是C++用户,VS是你的不二选择
对于C++用户在.h文件中有:
extern "C" LIBQYun_CAPI void hello ();
只要你用g++编译,无论你写的是啥,都得加上extern “C”
对于Java的文件目录结构,由于我用IDEA所以都自动生成好了
用VSCode创建Maven项目也会帮你创建好目录结构
但是会有一点不一样,一般来说,你会发现文件第一行有
package com.QYun.API; // 等类似的东西,也可能没有
接下来可能会捣鼓一下Linux下的施法方式(
Linux下是.so文件,记得好像比在Windows下要简单一些