大家好,欢迎来到IT知识分享网。
目录
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博客
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/23626.html