如何将负整数传递给COM/OLE函数
How to Pass Negative Integer to COM/OLE Function?
我正在基于Visual Studio 2010中基于C /ATL的Microsoft Word加载项。我还使用基于MFC的COleDispatchDriver
并支持类,并使用Visual Studio的ClassWizard生成了ClassWizardMicrosoft Word类型库中的包装类类。classwizard生成的选择函数的样本包装器在下面。
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;
}
对于上述功能,我还编写了助手功能来照顾通过的变体参数,如下所示。
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);
它看起来"似乎"一词将整数视为无符号整数,而我的-1值变为65535,导致选择向前跳。使用InvokeHelper
函数调用在线上检查vaCount
变体,VS调试器将.iVal
值显示为-1,但vaCount
变体的"值"显示为65535。
作为com函数呼叫的一部分,我缺少适当地传递负整数?
问题是您正在滥用VARIANT
。
您将vaCount
的vt
字段设置为VT_INT
1 ,但是然后将int
值分配给其.iVal
字段而不是其.intVal
字段。.iVal
字段是用于VT_I2
的16位short
,而.intVal
是VT_INT
使用的32bit int
。
同样,您将vaUnit
的vt
设置为VT_I4
,但随后也将int
值分配给其.iVal
字段,而不是其.lVal
字段,即32bit 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#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 两个 COM 组件中 ENUM 的重复条目
- COM 接口 c# 封送数组数组
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- 如何读取 C++ SAFEARRAY**,该 SAFEARRAY** 是 COM 互操作的结果,其中 C# 返回值为
- 进程外 EXE 的免注册 COM
- 使用 Outlook 2016 Microsoft Store 连接到 Outlook COM
- 如何从COM模块中的函数返回字符串数组?
- 如何在C++非托管/本机 DLL 中从注册免费 COM C# 托管 DLL 创建 COM 对象
- Windows (COM) API 的行为不同,没有特定的库
- 我是否可以使用 win32 句柄以编程方式记录发送到/接收到 USB/COM 的内容
- 在传递 com 变体时运行 excel 宏崩溃
- 从 WinRT C++组件访问 COM 对象
- c++ com 如何继承 IUIAutomationPropertyChangedEventHandler 接口
- OLE DB 大容量复制操作始终将 true 加载到位列中
- 如何将从控制台应用程序C++回调设置为C++ COM DLL
- 使用线程 C# 中的 VC++ 6.0 COM DLL
- 问题: 从 MFC 调用 C# 未托管 COM C++
- 如何调试 COM DLL
- 如何将负整数传递给COM/OLE函数