Java调用dll文件

3 篇文章 0 订阅

目录

1 C++创建dll

1.1 项目与工具

1.2 步骤与代码

2 Java使用JNA调用dll

2.1 项目与工具

2.2 步骤与代码

3 实际效果

4 参考链接


1 C++创建dll

1.1 项目与工具

Visual Studio 2019

1.2 步骤与代码

①使用VS创建动态链接库(DLL)项目

②设置项目名与项目地址

创建好的效果如下:

③创建choosefiles.cpp源文件和choosefiles.h头文件 

 

 ④choosefiles.h

#ifdef CHOOSEFILES_EXPORTS
#define CHOOSEFILES_API __declspec(dllexport)
#else
#define CHOOSEFILES_API __declspec(dllimport)
#endif

extern "C" CHOOSEFILES_API char* chooseFiles();

 ⑤choosefiles.cpp

#include "pch.h"
#include "framework.h"
#include "choosefiles.h"
#include <iostream>
#include <windows.h>
#include <Commdlg.h>
#include <tchar.h>

using namespace std;

/*
TCHAR*转char*
*/
char* LPWSTR2LPSTR(LPWSTR lpwszStrIn)
{
    LPSTR pszOut = NULL;
    if (lpwszStrIn != NULL) {
        int nInputStrLen = wcslen(lpwszStrIn);
        int nOutputStrLen = WideCharToMultiByte(CP_ACP, 0, lpwszStrIn, nInputStrLen, NULL, 0, 0, 0) + 2;
        pszOut = new char[nOutputStrLen];
        if (pszOut != NULL) {
            memset(pszOut, 0x00, nOutputStrLen);
            WideCharToMultiByte(CP_ACP, 0, lpwszStrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0);
        }
    }
    return  pszOut;
}

CHOOSEFILES_API char* chooseFiles() {

    OPENFILENAME ofn;
    TCHAR szOpenFileNames[80 * MAX_PATH] = { 0 };
    TCHAR szPath[MAX_PATH];
    TCHAR szFileName[80 * MAX_PATH];

    int nLen = 0;
    TCHAR* p = NULL;
    ZeroMemory(&ofn, sizeof(ofn));

    // 结构体大小
    ofn.lStructSize = sizeof(ofn);

    // 拥有着窗口句柄
    ofn.hwndOwner = NULL;

    // 接收返回的文件名,注意第一个字符需要为NULL
    ofn.lpstrFile = szOpenFileNames;

    // 缓冲区长度
    ofn.nMaxFile = sizeof(szOpenFileNames);

    // _T可替换为TEXT,使用_T需要引tchar.h
    ofn.lpstrFile[0] = _T('\0');

    // 设置过滤
    ofn.lpstrFilter = _T("All\0*.*\0.mp4\0*.mp4\0.avi\0*.avi\0.mkv\0*.mkv\0.rmvb\0*.rmvb\0.f4v\0*.f4v\0.flv\0*.flv\0.m4v\0*.m4v\0.mpg\0*.mpg\0\0");

    // 过滤器索引
    ofn.nFilterIndex = 1;

    // 窗口标题
    ofn.lpstrTitle = _T("请选择视频");

    // 文件必须存在、允许多选、隐藏只读选项、对话框使用资源管理器风格的用户界面
    // 官方文档:https://docs.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-openfilenamea
    ofn.Flags = OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY | OFN_EXPLORER;

    // 定义字符串,用于拼接所选的所有文件的完整路径
    string str = "***";

    // 如果打开文件失败,则不操作;打开成功才操作
    if (GetOpenFileName(&ofn)) {
        // 把第一个文件名前的复制到szPath,即:  
        // 如果只选了一个文件,就复制到最后一个'/'  
        // 如果选了多个文件,就复制到第一个NULL字符  
        lstrcpyn(szPath, szOpenFileNames, ofn.nFileOffset);

        // 当只选了一个文件时,下面这个NULL字符是必需的.  
        // 这里不区别对待选了一个和多个文件的情况
        szPath[ofn.nFileOffset] = '\0';
        nLen = lstrlen(szPath);

        // 如果选了多个文件,则必须加上'//'  
        if (szPath[nLen - 1] != '\\') {
            lstrcat(szPath, _T("\\"));
        }

        // 把指针移到第一个文件  
        p = szOpenFileNames + ofn.nFileOffset;

        // 对szFileName进行清零
        ZeroMemory(szFileName, sizeof(szFileName));

        while (*p) {
            // 读取文件名
            string fileName = LPWSTR2LPSTR(p);

            // 读取文件所在文件夹路径
            string filePath = LPWSTR2LPSTR(szPath);

            // 拼接文件完整路径
            string completePath = filePath + fileName;

            // 拼接字符串
            str += completePath + "***";

            //移至下一个文件
            p += lstrlen(p) + 1;
        }
    }

    // 将string转为char*
    char* strc = new char[strlen(str.c_str()) + 1];
    const char* cc = str.c_str();
    strcpy_s(strc, str.size() + 1, cc);

    return strc;
}

 ⑥改成64位程序(由于我使用的是64位的jdk,所以需要生成64位的dll)

 ⑦生成解决方案

生成成功提示如下:

dll文件:

2 Java使用JNA调用dll

2.1 项目与工具

idea、maven(选择maven-archetype-quickstart骨架)、Java8、JNA

2.2 步骤与代码

①创建好项目之后,创建resources文件夹,并将dll文件复制进去

②设置项目资源文件夹

设置好后结果如下:

③添加jna依赖并刷新maven

<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.5.0</version>
</dependency> 

④创建DLL接口

package cxzgwing;

import com.sun.jna.Library;
import com.sun.jna.Native;

public interface DLL extends Library {
    DLL dll = Native.load("choosefiles", DLL.class);

    String chooseFiles();
}

⑤调用

package cxzgwing;

public class App {
    public static void main(String[] args) {
        System.setProperty("jna.encoding", "GBK");
        System.out.println(DLL.dll.chooseFiles());
    }
}

3 实际效果

若点击取消,则输出三个星号(***):

 可选择显示的文件类型:

 

4 参考链接

[1] Aimls.Java使用JNA调用C/C++动态链接库dll.2019-07-26 14:44:22

Java使用JNA调用C/C++动态链接库dll_哔哩哔哩_bilibili

[2] 晨曦之光Wing.C++打开文件选择框多选文件.2021-10-09 00:03:40

C++打开文件选择框多选文件_晨曦之光Wing的博客-CSDN博客

你好!对于Java调用复杂的DLL文件接口,需要进行一些额外的步骤和注意事项。下面是一个一般性的指导: 1. 确保DLL文件可用:首先,确保你有正确的DLL文件,并且该DLL文件是针对Java编写的。如果DLL文件是为其他编程语言编写的,你可能需要使用Java本机接口(JNI)来进行交互。 2. 编写JNI接口:在Java中,使用JNI来与DLL文件进行交互。你需要编写一个本地方法,将其声明为native,并使用JNI来加载和调用DLL文件中的函数。JNI提供了一组函数来管理Java和本机代码之间的通信。 3. 生成头文件:通过Java本机接口开发工具(如javah)生成与你编写的JNI接口对应的头文件。这个头文件将包含函数声明和JNI函数的映射。 4. 实现JNI接口:在C/C++中实现JNI接口中定义的本地方法。这将涉及到与DLL文件的交互,包括函数调用和数据传递等。 5. 编译并链接:编译你的本地代码,并将其链接到Java代码中。这将生成一个可执行的Java文件,其中包含对DLL文件进行调用的本地方法。 6. 加载和使用DLL:在Java代码中加载生成的本地库,并通过调用本地方法来使用DLL中的功能。 需要注意的是,Java本机接口(JNI)需要一定的熟练程度,并且使用不当可能会导致内存泄漏或程序崩溃等问题。确保仔细阅读JNI文档,并遵循最佳实践。 希望这些步骤能帮助你成功调用复杂的DLL文件接口!如有更多问题,请随时提问。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值