QT/MinGW 4.8的SHChangeNotifyRegister无法链接 [英] SHChangeNotifyRegister with QT/MinGW 4.8 cannot link

查看:87
本文介绍了QT/MinGW 4.8的SHChangeNotifyRegister无法链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现一项功能,以便程序可以自动检测USB存储设备.

我了解我需要收听WM_DEVICECHANGE,并且已经使用QAbstractNativeEventFilter完成此操作,但这并不能解决特定情况,即SD卡已从读取器中插入或取出(或在我的特定情况下)按下手机上的打开大容量存储"按钮.

在一些谷歌搜索中,我发现了这篇文章:检测使用Windows消息将媒体插入驱动器中,它准确描述了我需要使用SHCNE_MEDIAINSERTEDSHCNE_MEDIAREMOVED的内容.

我的问题是我的链接器似乎找不到SHChangeNotifyRegister.在Qt Creator中,我正在获取slobj.h的代码完成声明,但是在编译时,我得到的是:

error: undefined reference to `_imp__SHChangeNotifyRegister@24'

然后ld失败,退出代码为1.

我对链接器找不到的内容不知所措,QtCreator内部的包含项很好-因此找不到shell32.dll吗?我正在运行mingw4.8 32bit,这是无法使用由其他编译器编译的dll的情况吗?我还尝试将win32: LIBS += -lshell32添加到我的.pro文件中无济于事,并且还将Windows 7 SDK的lib文件夹添加到我的path变量中.

我的代码如下(请注意,我对winapi毫无用处100%,因此该代码很可能因为我正在修补中而被严重破坏了):

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的.
  • mingw链接到其自己的shell32.a

  • 使用了我的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,我认为这是不可能的,或者将MSVC用于Windows构建.

因此,我认为我的问题的答案是:它没有链接,因为您的shell32.a在.h中不包含所有内容"?

答案:

结果证明mingw可以使用某些msvc .lib文件.因此,这次我正确地链接到了Windows SDK版本的shell32.lib,一切似乎都可以正常工作.简而言之,这需要添加到我的.pro文件中:

win32: LIBS += -L"C:/Path/To/Microsoft/Microsoft SDKs/Windows/v7.1/Lib/" -lshell32

解决方案

这样我就可以接受这个问题的答案了,我将在此处发布解决方案.

读凯里(Carey)和迈克尔(Michael)关于这个问题的评论,就使我了解了哪里出了问题.

听起来您要么出于某种原因未与Shell32.lib链接,要么您的Shell32.lib没有导出_SHChangeNotifyRegister @ 24函数.尝试找到Shell32.lib文件,在命令提示符下键入"dumpbin/exports shell32.lib",然后查看_SHChangeNotifyRegister @ 24函数是否已导出

基本上,与mingw链接的shell32.a缺少SHChangeNotifyRegister的定义(shlobj.h的mingw版本具有此声明)-您可以阅读我在问题更新中得出的结论. /p>

要解决此问题,我使用了我从Windows SDK拷贝的shell32.lib副本-我认为可以在

I'm trying to implement a feature whereby USB storage devices are auto detected by my program.

I understand that I need to listen for WM_DEVICECHANGE, and have done using a QAbstractNativeEventFilter but this doesn't catch a specific case which is an SD card being inserted or removed from a reader (or in my specific case pushing the "Turn on mass storage" button on my phone).

Upon some Googling I found this post: Detect insertion of media into a drive using windows messages which describes exactly what I need which makes use of SHCNE_MEDIAINSERTED and SHCNE_MEDIAREMOVED.

My Problem is that my linker can't seem to find SHChangeNotifyRegister. Inside of Qt Creator I'm getting the code completion declarations for slobj.h, but upon compiling I get this:

error: undefined reference to `_imp__SHChangeNotifyRegister@24'

Then ld fails with exit code 1.

I'm at a loss as to what the linker cannot find, the includes are fine inside QtCreator - so can it not find shell32.dll? I'm running mingw4.8 32bit is this a case of it being unable to use a dll compiled with a different compiler? I've also tried adding win32: LIBS += -lshell32 to my .pro file to no avail, and also added the lib folder of a windows 7 SDK to my path variable.

My code is as follows (note that I'm 100% useless with winapi so this code is likely massively broken as I was in the middle of tinkering with it):

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
);

Comments also welcome that might help me better formulate this question.

UPDATE:

Following Carey and Michaels suggestions in the notes I have figured out a few things:

  • I'm not using the shell32.lib from the Windows SDK because I think that is for MSVC.
  • mingw links against its own shell32.a

  • Having used objdump -x shell32.a from my mingw distribution I can find no reference to SHChangeNotifyRegister.

  • Using objdump -x shell32.lib on the shell32.lib from the windows SDK I can find the line:

    [  3](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __imp__SHChangeNotifyRegister@24
    

This makes me believe that the shell32.a distributed with mingw 4.8 is incomplete and therefore my program will not link.

So I think I shall explore either a more recent version of mingw if one exists OR linking against the WindowsSDK with mingw which I believe is impossible OR using MSVC for my windows builds.

So therefore I think the answer to my question is: "It doesn't link because your shell32.a doesn't contain everything in the .h"?

ANSWER:

Turns out mingw can use certain msvc .lib files. So this time I linked properly to the Windows SDK version of shell32.lib and everything seems to work. In short this needed to be added to my .pro file:

win32: LIBS += -L"C:/Path/To/Microsoft/Microsoft SDKs/Windows/v7.1/Lib/" -lshell32

解决方案

So that I can accept an answer on this question I'll post up the solution here.

Reading Carey and Michael's comments on the question gave me the a clue as to what was wrong.

It sounds that either you dont link with Shell32.lib for some reason or that your Shell32.lib doesn't export the _SHChangeNotifyRegister@24 function. Try to find the Shell32.lib file, type "dumpbin /exports shell32.lib" at a command prompt and look if the _SHChangeNotifyRegister@24 function is exported

Essentially the shell32.a that mingw was linking against lacked the definition of SHChangeNotifyRegister (the mingw version of shlobj.h had this declaration) - you can read how I came to that conclusion in the updates of the question.

To fix the solution I used a copy of shell32.lib from a Windows SDK that I had laying around - I think this can be found here. Luckily mingw could link that .lib file.

To link the new shell32.lib with my QT Qbuild .pro file I used the following:

win32: LIBS += -L"C:/Path/To/Microsoft/Microsoft SDKs/Windows/v7.1/Lib/" -lshell32

这篇关于QT/MinGW 4.8的SHChangeNotifyRegister无法链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆