我有一个使用
WMI
来获取 smbios
数据的模块。 WMI
虽然COM
界面,没什么特别的。它编译得很好但是当我使用在应用程序中创建的静态库时链接失败:
[ilink32 错误] 错误:未解析的外部 '__stdcall _com_issue_error(long)' 引用自 Libname|modname
这应该在
comsupp
或 comsuppw
库中但是,#pragma comment(lib, "comsuppw");
导致错误,它找不到 COMSUPPW.LIB
(我也尝试了不同的命名:comsupp,comsuppwd)
我读到这个库只包含在 Visual Studio 中,但我使用 C++ 构建器来构建它。它似乎不会构建它无法链接到的东西。在 C++ Builder 中是否有其他库可以解决这个问题?
FWIW 这是包括处理 com:
#include <comdef.h>
#include <Wbemidl.h>
#include <oaidl.h>
#pragma comment(lib, "wbemuuid.lib")
编辑:
我将 Microsoft
comsupp
库转换为 OMF/ELF 但同样的问题,所以它一定不在那个库中。
我看到函数在
comutil.cpp
中,包含在 c++ 构建器中,但是没有 comutil
库可以链接,是否应该使用另一个库?我在主 .cpp 模块(带有 #include <comutil.cpp>
的模块)中使用 _tWinMain
但它没有改变任何东西,也许是命名空间问题......
不过,我只是尝试将下面的代码添加到我的主模块中,但这给出了
ISO C++ 17 不允许动态异常规范
#include <comdef.h>
#pragma option push -b -a8 -pc -A- /*P_O_Push*/
void __stdcall _com_raise_error(HRESULT hr, IErrorInfo* perrinfo) throw (_com_error)
{
throw _com_error(hr, perrinfo);
}
void __stdcall _com_issue_error(HRESULT hr) throw(_com_error)
{
throw _com_error(hr);
}
void _stdcall _com_issue_errorex(HRESULT hr, IUnknown*, REFIID) throw(_com_error){
throw _com_error(hr);
}
#pragma option pop /*P_O_Pop*/
这应该怎么做?
库相关的bug有两个:
comdef.h 不是有效的 C++17,应该在 C++ Builder 10.3.2 中修复。但是下面的代码也修复了它。
Could not use comutil.h in any project, you can fix by creating
_com_issue_error
your own.
#pragma comment(lib, "wbemuuid.lib")
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wkeyword-macro"
// This is needed because comdef.h in C++ Builder 10.3 is not valid C++17
#if __cplusplus >= 201703L
#define throw(...)
#endif
#define _WIN32_DCOM
#include <comdef.h>
#include <Wbemidl.h>
#if __cplusplus >= 201703L
#undef throw
#endif
#pragma clang diagnostic pop
// Implemented here because comsupp.lib is missing from C++ Builder 10.1.
void __stdcall _com_issue_error(HRESULT hr)
{
throw _com_error(hr);
}