如何将 std::variant 作为 VARIANT* 传递给 ExecWB?
How can I pass a std::variant as a VARIANT* to ExecWB?
我看过这篇关于使用 std::variant
的文章。这是因为以下代码引发了代码分析警告:
void CChristianLifeMinistryHtmlView::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == ID_TIMER_ZOOM)
{
//get the zoom value
VARIANT vZoom{};
vZoom.vt = VT_I4;
vZoom.lVal = 0;
ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, nullptr, &vZoom);
TRACE("zoom %d\n", vZoom.lVal);
//kill the timer
KillTimer(nIDEvent);
GetParent()->PostMessage(UWM_HTMLVIEW_CHANGE_ZOOM_MSG, vZoom.lVal);
return;
}
CHtmlView::OnTimer(nIDEvent);
}
警告:
Warning C26476: Expression/symbol {{0, 0, 0, 0, {0}}}
uses a naked union 'union ' with multiple type pointers: Use variant
instead (type.7).
我开始尝试更改代码:
void CChristianLifeMinistryHtmlView::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == ID_TIMER_ZOOM)
{
//get the zoom value
std::variant<long> vZoom(0);
ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, nullptr, &vZoom);
TRACE("zoom %d\n", vZoom.lVal);
//kill the timer
KillTimer(nIDEvent);
GetParent()->PostMessage(UWM_HTMLVIEW_CHANGE_ZOOM_MSG, vZoom.lVal);
return;
}
CHtmlView::OnTimer(nIDEvent);
}
但问题是 ExecWB
需要一个 VARIANT *
而我不知道如何传递这个 std::variant
.
抱歉,您不能在此处使用 std::variant
。
VARIANT
是 COM 中用于不同组件互操作的类型,即使用不同的语言编写并驻留在不同的进程中也是如此。
std::variant
提供作为模板参数传递的任意类型集的类型安全变体。即使两个std::variant
模板参数不同也不兼容,其中none兼容VARIANT
.
使程序更健壮的最佳方法是使用来自 ATL 的 CComVariant
,或 find/create VARIANT
结构的另一个包装器。不确定它是否会使警告消失。
诊断是正确的,尽管建议过于笼统而无用。虽然 std::variant
通常是表示 COM 中使用的类型安全 discriminated unions, it is unrelated to the VARIANT
结构的好方法。
在这种情况下,您需要使用不同的类型,例如 Microsoft 的 _variant_t
class。它封装了原始 VARIANT
,并处理了其可区分联合的内部结构。
它提供了几个正确管理设置内部状态的构造函数,并从 VARIANT
派生,因此任何实例的地址都可以传递给任何接受 VARIANT*
:
的函数
#include <comutil.h>
#pragma comment(lib, "comsuppw.lib")
int main() {
auto zoom{ _variant_t(long{ 0 }) };
ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, nullptr, &zoom);
}
我看过这篇关于使用 std::variant
的文章。这是因为以下代码引发了代码分析警告:
void CChristianLifeMinistryHtmlView::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == ID_TIMER_ZOOM)
{
//get the zoom value
VARIANT vZoom{};
vZoom.vt = VT_I4;
vZoom.lVal = 0;
ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, nullptr, &vZoom);
TRACE("zoom %d\n", vZoom.lVal);
//kill the timer
KillTimer(nIDEvent);
GetParent()->PostMessage(UWM_HTMLVIEW_CHANGE_ZOOM_MSG, vZoom.lVal);
return;
}
CHtmlView::OnTimer(nIDEvent);
}
警告:
Warning C26476: Expression/symbol
{{0, 0, 0, 0, {0}}}
uses a naked union 'union ' with multiple type pointers: Usevariant
instead (type.7).
我开始尝试更改代码:
void CChristianLifeMinistryHtmlView::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == ID_TIMER_ZOOM)
{
//get the zoom value
std::variant<long> vZoom(0);
ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, nullptr, &vZoom);
TRACE("zoom %d\n", vZoom.lVal);
//kill the timer
KillTimer(nIDEvent);
GetParent()->PostMessage(UWM_HTMLVIEW_CHANGE_ZOOM_MSG, vZoom.lVal);
return;
}
CHtmlView::OnTimer(nIDEvent);
}
但问题是 ExecWB
需要一个 VARIANT *
而我不知道如何传递这个 std::variant
.
抱歉,您不能在此处使用 std::variant
。
VARIANT
是 COM 中用于不同组件互操作的类型,即使用不同的语言编写并驻留在不同的进程中也是如此。
std::variant
提供作为模板参数传递的任意类型集的类型安全变体。即使两个std::variant
模板参数不同也不兼容,其中none兼容VARIANT
.
使程序更健壮的最佳方法是使用来自 ATL 的 CComVariant
,或 find/create VARIANT
结构的另一个包装器。不确定它是否会使警告消失。
诊断是正确的,尽管建议过于笼统而无用。虽然 std::variant
通常是表示 COM 中使用的类型安全 discriminated unions, it is unrelated to the VARIANT
结构的好方法。
在这种情况下,您需要使用不同的类型,例如 Microsoft 的 _variant_t
class。它封装了原始 VARIANT
,并处理了其可区分联合的内部结构。
它提供了几个正确管理设置内部状态的构造函数,并从 VARIANT
派生,因此任何实例的地址都可以传递给任何接受 VARIANT*
:
#include <comutil.h>
#pragma comment(lib, "comsuppw.lib")
int main() {
auto zoom{ _variant_t(long{ 0 }) };
ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, nullptr, &zoom);
}