QT/MinGW 4.8的SHChangeNotifyRegister无法链接
SHChangeNotifyRegister with QT/MinGW 4.8 cannot link
我正在尝试实现一个功能,通过该功能,我的程序可以自动检测USB存储设备。
我知道我需要监听WM_DEVICECHANGE
,并且已经使用了QAbstractNativeEventFilter
,但这并不能捕捉到一个特定的情况,即插入或从读卡器中取出SD卡(或者在我的特定情况下,按下手机上的"打开大容量存储"按钮)。
在谷歌上搜索后,我发现了这篇文章:使用windows消息检测媒体插入驱动器,该消息准确描述了我使用SHCNE_MEDIAINSERTED
和SHCNE_MEDIAREMOVED
所需要的内容。
我的问题是我的链接器似乎找不到SHChangeNotifyRegister
。在QtCreator内部,我得到了slobj.h
的代码完成声明,但在编译时,我得到的是:
error: undefined reference to `_imp__SHChangeNotifyRegister@24'
然后ld
失败,退出代码为1。
我不知道链接器找不到什么,包括在QtCreator中很好,所以它找不到shell32.dll
吗?我正在运行mingw4.8 32bit
,这是因为它无法使用用其他编译器编译的dll吗?我还尝试将win32: LIBS += -lshell32
添加到.pro文件中,但没有成功,还将windows7SDK的lib
文件夹添加到我的路径变量中。
我的代码如下(请注意,我对winapi百分之一百没用,所以当我正在修改它时,这个代码可能会被严重破坏):
MainWindow w(deviceMgr);
w.show();
int sources = 0x0001 | 0x0002 | 0x8000; // Interupt, Shell, New Delivery Missing Defs
LONG events = SHCNE_MEDIAINSERTED | SHCNE_MEDIAREMOVED;
PIDLIST_ABSOLUTE pidl;
SHGetFolderLocation((HWND) w.winId(), CSIDL_DRIVES, NULL, 0, &pidl);
SHChangeNotifyEntry entries[] = { pidl, false };
ULONG code = SHChangeNotifyRegister(
(HWND) w.winId(),
sources,
events,
WM_APP + 1,
ARRAYSIZE(entries),
entries
);
也欢迎发表意见,这可能有助于我更好地阐述这个问题。
更新:
根据Carey和Michaels在笔记中的建议,我发现了一些事情:
- 我没有使用Windows SDK中的shell32.lib,因为我认为这是用于MSVC的
明与自己的外壳相连32.
在使用了我的mingw发行版中的
objdump -x shell32.a
之后,我找不到SHChangeNotifyRegister的引用。在windows SDK的
shell32.lib
上使用objdump -x shell32.lib
,我可以找到以下行:[ 3](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __imp__SHChangeNotifyRegister@24
这让我相信与mingw 4.8一起分发的shell32.a是不完整的,因此我的程序将不会链接。
因此,我认为我应该探索mingw的最新版本(如果存在),或者使用mingw链接WindowsSDK(我认为这是不可能的),或者在我的windows构建中使用MSVC。
因此,我认为我的问题的答案是:"它没有链接,因为你的外壳32.a不包含.h中的所有内容"?
答案:
原来mingw可以使用某些msvc.lib文件。所以这次我正确地链接到了shell32.lib的WindowsSDK版本,一切似乎都正常了。简而言之,这需要添加到我的.pro
文件中:
win32: LIBS += -L"C:/Path/To/Microsoft/Microsoft SDKs/Windows/v7.1/Lib/" -lshell32
为了接受这个问题的答案,我将在这里发布解决方案。
读了凯里和迈克尔对这个问题的评论,我知道问题出在哪里。
听起来,要么是由于某种原因您没有链接到Shell32.lib,要么是您的Shell32.lib没有导出_SHChangeNotifyRegister@24作用尝试查找Shell32.lib文件,在命令提示符下键入"dumpbin/exports-Shell32.lib",然后查看_SHChangeNotifyRegister@24功能导出
从本质上讲,mingw所链接的shell32.a
缺乏SHChangeNotifyRegister
的定义(shlobj.h
的mingw版本有这个声明)——你可以在问题的更新中阅读我是如何得出这个结论的。
为了修复这个解决方案,我使用了一份来自Windows SDK的shell32.lib
副本,我想这可以在这里找到。幸运的是,mingw可以链接该.lib文件。
为了将新的shell32.lib
与我的QT Qbuild .pro
文件链接,我使用了以下内容:
win32: LIBS += -L"C:/Path/To/Microsoft/Microsoft SDKs/Windows/v7.1/Lib/" -lshell32
我在编译应用程序时遇到了类似的错误。我想用MSVC 2013工具包构建Qt Creator。我的.pro
文件中有LIBS += -ladvapi32
,但仍然得到:
FilePathUtilities.obj : error LNK2019:
unresolved external symbol __imp_ShellExecuteExW
referenced in function "void __cdecl FileShowInExplorer(class CStr const &,int)"
问题最终很简单:我使用x64 MSVC工具包而不是32位工具包进行构建!
我不知道为什么,我不是C++开发人员,但看起来32位和64位的标识符不完全相同:
/* 32 BIT LIBRARY */
/c/Program Files (x86)/Microsoft SDKs/Windows/v7.1A/Lib
$ "C:Program Files (x86)Microsoft Visual Studio 12.0VCbindumpbin.exe" -exports shell32.lib | grep ShellEx
_WOWShellExecute@28
_ShellExecuteW@24
_ShellExecuteExW@4
_ShellExecuteExA@4
_ShellExecuteEx@4
_ShellExecuteA@24
/* 64 BIT LIBRARY */
/c/Program Files (x86)/Microsoft SDKs/Windows/v7.1A/Lib/x64
$ "C:Program Files (x86)Microsoft Visual Studio 12.0VCbinx86_amd64dumpbin.exe" -exports shell32.lib | grep ShellEx
ShellExecuteA
ShellExecuteEx
ShellExecuteExA
ShellExecuteExW
ShellExecuteW
WOWShellExecute
- 没有找到相关文章