gpt4 book ai didi

c++ - 如何将负整数传递给 COM/OLE 函数?

转载 作者:行者123 更新时间:2023-11-28 01:24:17 25 4
gpt4 key购买 nike

我正在 Visual Studio 2010 中开发基于 C++/ATL 的 Microsoft Word 加载项。我还使用基于 MFC 的 COleDispatchDriver 和支持类,并使用 Visual Studio 的 ClassWizard 生成包装器Microsoft Word 类型库中的类。下面是 ClassWizard 生成的 Selection.Move 函数的示例包装器。

long Move(VARIANT * Unit, VARIANT * Count)
{
long result;
static BYTE parms[] = VTS_PVARIANT VTS_PVARIANT ;
InvokeHelper(0x6d, DISPATCH_METHOD, VT_I4, (void*)&result, parms, Unit, Count);
return result;
}

对于像上面这样的函数,我还编写了辅助函数来处理 VARIANT 参数传递,如下所示。

long Move(int Unit, int Count)
{
long result;
static BYTE parms[] = VTS_PVARIANT VTS_PVARIANT ;

VARIANT vaUnit;
::VariantInit(&vaUnit);
vaUnit.vt = VT_I4;
vaUnit.iVal = Unit;

VARIANT vaCount;
::VariantInit(&vaCount);
vaCount.vt = VT_INT;
vaCount.iVal = Count;

InvokeHelper(0x6d, DISPATCH_METHOD, VT_I4, (void*)&result, parms, &vaUnit, &vaCount);

::VariantClear(&vaUnit);
::VariantClear(&vaCount);

return result;
}

当我为 Count 参数调用我的函数时,Word 会正确响应,例如以下函数调用会将选择“向前”(向文档末尾)移动一个字符。

m_oSelection.Move(1 /* wdCharacter */, 1);

但是,如果我尝试使用以下函数调用将所选内容“向后”移动一个字符(朝向文档的开头),Word 不会按预期进行响应。

m_oSelection.Move(1 /* wdCharacter */, -1);

“似乎”Word 自动化将整数视为无符号整数,而我的 -1 值变为 65535,导致选择向前跳转。使用 InvokeHelper 函数调用检查行上的 vaCount 变体,VS 调试器将 .iVal 值显示为 -1,但“值vaCount 变体的 "显示为 65535。

为了在 COM 函数调用中适本地传递负整数,我错过了什么?

最佳答案

问题是您滥用了 VARIANT

您正在将 vaCountvt 字段设置为 VT_INT 1 但随后分配您的 int 值到其 .iVal 字段而不是其 .intVal 字段。 .iVal 字段是用于 VT_I2 的 16 位 short,而 .intVal 是一个 32 位 intVT_INT 一起使用。

同样,您将 vaUnitvt 设置为 VT_I4,然后将您的 int 值分配给它的 .iVal 字段,而不是它的 .lVal 字段,它是一个 32 位 long

1:为什么您完全使用 VT_INT,而不是更传统的 VT_I4

试试这个:

long Move(int Unit, int Count)
{
long result;
static BYTE parms[] = VTS_PVARIANT VTS_PVARIANT ;

VARIANT vaUnit;
::VariantInit(&vaUnit);
vaUnit.vt = VT_I4;
vaUnit.lVal = Unit;

VARIANT vaCount;
::VariantInit(&vaCount);
vaCount.vt = VT_I4;
vaCount.lVal = Count;

InvokeHelper(0x6d, DISPATCH_METHOD, VT_I4, (void*)&result, parms, &vaUnit, &vaCount);

::VariantClear(&vaUnit);
::VariantClear(&vaCount);

return result;
}

话虽如此,我建议您使用 CComVariant_variant_t包装类而不是直接使用 VARIANT,让它为您处理这些细节。此外,因为 InvokeHelper() 会在失败时抛出异常,所以让包装器在超出范围时为您调用 VariantClear():

long Move(int Unit, int Count)
{
long result;
static BYTE parms[] = VTS_PVARIANT VTS_PVARIANT ;

CComVariant vaUnit(Unit);
CComVariant vaCount(Count);

InvokeHelper(0x6d, DISPATCH_METHOD, VT_I4, (void*)&result, parms, &vaUnit, &vaCount);

return result;
}

long Move(int Unit, int Count)
{
long result;
static BYTE parms[] = VTS_PVARIANT VTS_PVARIANT ;

_variant_t vaUnit(Unit);
_variant_t vaCount(Count);

InvokeHelper(0x6d, DISPATCH_METHOD, VT_I4, (void*)&result, parms, &vaUnit, &vaCount);

return result;
}

关于c++ - 如何将负整数传递给 COM/OLE 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54681194/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com