如何将std::variant作为variant *传递给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 %dn", vZoom.lVal);
//kill the timer
KillTimer(nIDEvent);
GetParent()->PostMessage(UWM_HTMLVIEW_CHANGE_ZOOM_MSG, vZoom.lVal);
return;
}
CHtmlView::OnTimer(nIDEvent);
}

警告:

警告C26476:表达式/符号{{0, 0, 0, 0, {0}}}使用带有多个类型指针的裸联合'union ':使用variant代替(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 %dn", 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通常是表示类型安全区分联合的好方法,但它与COM中使用的VARIANT结构无关。

在这种情况下,您需要使用不同的类型,例如Microsoft的_variant_t类。它封装了原始的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

VARIANT是COM中用于不同组件互操作的类型,即使是用不同的语言编写并驻留在不同的进程中。

std::variant提供了作为模板形参传递的任意类型集的类型安全变体。如果两个std::variant具有不同的模板参数,则它们是不兼容的,并且它们都不与VARIANT兼容。

使程序更健壮的最好方法是使用ATL中的CComVariant,或者为VARIANT结构找到/创建另一个包装器。但我不确定它是否会让警告消失。

相关内容

  • 没有找到相关文章

最新更新