在 VS Code 中使用 C++ COM/IFileDialog 时出错,而在 Visual Studio 中使用相同的代码。消息:“IID_IFileOpenDialog”未在此范围内声明

Posted

技术标签:

【中文标题】在 VS Code 中使用 C++ COM/IFileDialog 时出错,而在 Visual Studio 中使用相同的代码。消息:“IID_IFileOpenDialog”未在此范围内声明【英文标题】:Error using C++ COM/IFileDialog in VS Code while the same code works in Visual Studio. Message: 'IID_IFileOpenDialog' was not declared in this scope 【发布时间】:2021-08-26 01:05:34 【问题描述】:

我有 C++ 代码,我试图用组件对象模型的 IFileDialog 打开一个文件选择对话框。该代码可以在 Visual Studio 中运行,但是当我在 VS Code 中键入完全相同的代码时,会出现 2 个错误:

IID_IFileOpenDialog' was not declared in this scope

invalid use of incomplete type 'IFileDialog' aka 'struct IFileDialog'

这是在 Visual Studio 中成功加载文件选择对话框的代码:

#include <iostream>
#include <objbase.h>
#include <ShObjIdl.h>

int main()

    CoInitializeEx(nullptr, COINIT::COINIT_MULTITHREADED);

    IFileDialog *fileDialog;
    HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_ALL, IID_IFileOpenDialog, reinterpret_cast<void**>(&fileDialog));

    if (SUCCEEDED(hr)) 
        fileDialog->AddRef();
        fileDialog->Show(NULL);
    
    else 
        std::cout << "no" << std::endl;
    

    CoUninitialize();

在 VS Code 中,我使用的是 MinGW/gcc/g++ 编译器(抱歉,我对编译器了解不多,但我认为这三个编译器都能让我的代码运行),而在 Visual Studio 中我不是当然,在绿色播放按钮旁边显示的是本地 Windows 调试器。

是什么导致这个错误只出现在 VS Code 中?

【问题讨论】:

与您的问题无关,但您的fileDialog 变量需要声明为IFileOpenDialog*,因为这是您要求CoCreateInstance() 输出的内容。您应该使用IID_PPV_ARGS() 宏来避免这种不匹配,例如:IFileOpenDialog *fileDialog; HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&amp;fileDialog)); gcc 的哪个版本和发行版? (mingw 和 mingw-64 是不同的项目;并且是具有各种不同二进制包的源代码分发) 您的程序在 mingw-w64 目标 x64_64-w64-mingw32,gcc 版本 10.3.0 - MSYS2 中为我正确构建和运行 我确信可以将 VS Code 与 microsoft 编译器一起使用 @M.M 我想我用的是mingw-64,我的gcc版本是6.3.0 【参考方案1】:

默认情况下,MinGW 似乎将 NTDDI_VERSION 宏的值设置为 0x05020000 (NTDDI_WS03),这会禁用 shobjidl.h 中的 IFileDialog 定义。宏的值必须至少为 0x06000000 (NTDDI_VISTA) 才能启用定义。此处列出了这些宏的可能值及其含义:

https://docs.microsoft.com/en-us/windows/win32/winprog/using-the-windows-headers

将以下内容放在源文件的开头(在包含之前)应该可以修复编译错误:

#define NTDDI_VERSION 0x0A000006 //NTDDI_WIN10_RS5
#define _WIN32_WINNT 0x0A00 // _WIN32_WINNT_WIN10, the _WIN32_WINNT macro must also be defined when defining NTDDI_VERSION

如果您没有链接所需的库,可能仍然会出现链接错误。您列出的程序需要 ole32.dll 和 uuid.dll,因此编译命令如下所示:

x86_64-w64-mingw32-g++ -static-libgcc -static-libstdc++ program.cpp -lole32 -luuid

MSDN 并不总是记录需要链接哪些 DLL 才能访问哪些符号(或者至少,我在搜索它时找不到信息),但是一种快速而肮脏的方法是在 MinGW 的 lib 目录中使用 grep。例如,当找到提供符号“CLSID_FileOpenDialog”的库时:

$ grep -r CLSID_FileOpenDialog /usr/x86_64-w64-mingw32/lib
Binary file /usr/x86_64-w64-mingw32/lib/libuuid.a matches

所以我们知道要在编译命令中添加“-luuid”

【讨论】:

我建议在构建系统中包含定义可能是个好主意,以避免不同的翻译单元看到不同版本的 windows 标头,这可能会导致棘手的问题 @Sarah D. 非常感谢,这解决了它,我现在可以在 VS Code 中使用 COM,你真是个天才。 补充我的其他评论,我对编译器和像这样的高级计算机知识还不是很了解,所以我无法做到你在这里描述的所有事情,但我能做到的事情找出解决问题。对于遇到此问题的任何人,这就是我所做的:就像 Sarah 所说,我将这些 #define 语句添加到源文件的顶部。然后我在我的tasks.json的args部分添加了“-lole32”和“-luuid”,程序就开始工作了。再次感谢!

以上是关于在 VS Code 中使用 C++ COM/IFileDialog 时出错,而在 Visual Studio 中使用相同的代码。消息:“IID_IFileOpenDialog”未在此范围内声明的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 VS Code 调试器在我的 C++ 代码周围弹跳?

在 VS Code 中使用 C++ COM/IFileDialog 时出错,而在 Visual Studio 中使用相同的代码。消息:“IID_IFileOpenDialog”未在此范围内声明

VS Code创建第一个C++项目-环境配置

VS Code 配置C++ 详解

如何用Code Blocks创建C++控制台项目

VS Code 中的 Lambda 表达式 C++ 错误