在 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(&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”未在此范围内声明