QT/MinGW 4.8的SHChangeNotifyRegister无法链接

SHChangeNotifyRegister with QT/MinGW 4.8 cannot link

本文关键字:SHChangeNotifyRegister 链接 MinGW QT      更新时间:2023-10-16

我正在尝试实现一个功能,通过该功能,我的程序可以自动检测USB存储设备。

我知道我需要监听WM_DEVICECHANGE,并且已经使用了QAbstractNativeEventFilter,但这并不能捕捉到一个特定的情况,即插入或从读卡器中取出SD卡(或者在我的特定情况下,按下手机上的"打开大容量存储"按钮)。

在谷歌上搜索后,我发现了这篇文章:使用windows消息检测媒体插入驱动器,该消息准确描述了我使用SHCNE_MEDIAINSERTEDSHCNE_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
相关文章:
  • 没有找到相关文章