Java调用C++ 动态链接库(*.dll) – JNA

JNA可以让你像调用一般java方法一样直接调用本地Dll动态链接库。就和直接执行本地方法差不多,而且调用本地方法还不用额外的其他处理或者配置什么的,也不需要多余的引用或者编码,使用很方便。

依赖Jar

jna(Releases -> 5.2)


Win Api

这里随便找个windows下的api测试
为了简单直观,就直接用user32.dll中的MessageBox这个函数,效果就是弹出一个信息框

百度找了份中文的Api文档,包含参数列表


JavaTest

Java代码如下
user32因为是在环境变量下,所以可以直接输入相对路径,.dll后缀也可以不写
参数/方法名/返回值与相应的Api对应

public class JNATestDll {

    /*
    user32.dll
    MessageBoxA
    参数名 类型  传址  数组  备注
    hWnd    整数型         窗口句柄
    lpText  文本型         提示内容
    lpCaption   文本型         提示标题
    uType   整数型         提示图标和按钮类型
    */

    public interface Dll extends Library {

        // 调用系统DLL
        int MessageBoxA(int hWnd, String content, String title, int uType);
        Dll instance = (Dll) Native.load("user32", Dll.class);
    }
    public static void main(String[] args) {
        System.out.println(Dll.instance.MessageBoxA(0,"Content内容","Title标题", 0x0));
    }
}

运行Main方法
调用成功


手写Dll

接下来手写一个Dll,这块有个坑,刚开始图简单用C#写了一个dll发现调用不了,后来了解得知,想调用C#的Dll 必须先由c/c++ 调用 c# ,然后Java在调用c/c++,相当于多了一层操作
所以还是直接手写一个c++的dll吧

VS 新建一个项目 选择 c++ 的动态链接库

定义一个函数
这个函数有一个int参数,同事调用一个MessageBox信息框
之后retu int值+10

int echoAge(int age) {
    MessageBox(NULL, TEXT("Hello,world!"), TEXT(""), MB_OK);
    return age + 10;
}

头文件中暴漏Api接口

#define MYLIBAPI extern "C" __declspec(dllexport)
MYLIBAPI int echoAge(int age);

然后编译/生成解决方案

注意这里编译的时候,要注意jdk 64位 ,dll也必须是64位

然后将生成的Dll放到Java项目中的ClassPath下


JavaTest

public class JNATestDll {

    public interface Dll extends Library {

        // 调用自定义 DLL
        Dll instance = (Dll) Native.load("MyDll-Project", Dll.class);
        int echoAge(int age );
    }
    public static void main(String[] args) {
        System.out.println(Dll.instance.echoAge(122));
    }
}

Main方法Run

调用成功

voidm

在黑暗中支撑和平的无名者

留下你的评论

*评论支持代码高亮<pre class="prettyprint linenums">代码</pre>

相关推荐