You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写单元测试调用Calculate函数及构建含2和0.8的VARIANT*参数

如何构建VARIANT*数组参数并编写Calculate函数的单元测试

我来帮你一步步搞定这两个问题——先解决怎么构建符合要求的VARIANT*参数,再给你写单元测试的示例,咱们慢慢来:

一、构建包含2和0.8的VARIANT*参数

因为Calculate要求的是指向VARIANT数组的指针(类型是VT_ARRAY | VT_VARIANT),所以核心是先创建COM的安全数组(SAFEARRAY),再把它包装到VARIANT里,最后取这个VARIANT的地址就行。以下是完整的代码实现:

// 1. 初始化要放入数组的两个元素
VARIANT intVar, floatVar;
VariantInit(&intVar); // 必须初始化每个VARIANT
VariantInit(&floatVar);

// 设置第一个元素为整数2(类型VT_I4)
V_VT(&intVar) = VT_I4;
V_I4(&intVar) = 2;

// 设置第二个元素为浮点数0.8(类型VT_R8)
V_VT(&floatVar) = VT_R8;
V_R8(&floatVar) = 0.8;

// 2. 创建SAFEARRAY的边界描述:一维数组,共2个元素,下界从0开始
SAFEARRAYBOUND saBound;
saBound.cElements = 2;
saBound.lLbound = 0;

// 创建存储VARIANT类型的SAFEARRAY
SAFEARRAY* pSafeArray = SafeArrayCreate(VT_VARIANT, 1, &saBound);
if (!pSafeArray) {
    // 处理创建失败的情况,记得先清理已初始化的VARIANT
    VariantClear(&intVar);
    VariantClear(&floatVar);
    return E_OUTOFMEMORY;
}

// 3. 将两个元素写入SAFEARRAY
long indices[1]; // 一维数组的索引

// 写入第一个元素(索引0)
indices[0] = 0;
HRESULT hr = SafeArrayPutElement(pSafeArray, indices, &intVar);
if (FAILED(hr)) {
    SafeArrayDestroy(pSafeArray);
    VariantClear(&intVar);
    VariantClear(&floatVar);
    return hr;
}

// 写入第二个元素(索引1)
indices[0] = 1;
hr = SafeArrayPutElement(pSafeArray, indices, &floatVar);
if (FAILED(hr)) {
    SafeArrayDestroy(pSafeArray);
    VariantClear(&intVar);
    VariantClear(&floatVar);
    return hr;
}

// 4. 把SAFEARRAY包装到VARIANT中,现在&arrayVar就是需要的VARIANT*参数
VARIANT arrayVar;
VariantInit(&arrayVar);
V_VT(&arrayVar) = VT_ARRAY | VT_VARIANT; // 标记为VARIANT数组
V_ARRAY(&arrayVar) = pSafeArray;

// 用完之后一定要清理:VariantClear会自动销毁内部的SAFEARRAY,以及里面的VARIANT元素
// VariantClear(&arrayVar);
// VariantClear(&intVar);
// VariantClear(&floatVar);

二、编写Calculate函数的单元测试

假设我们用Google Test框架来写测试(你也可以用其他框架,甚至写一个简单的控制台测试程序,逻辑是一样的),示例代码如下:

#include <gtest/gtest.h>
#include "MyCom.h" // 引入你的COM组件头文件

TEST(MyComCalculateTest, ValidVariantArrayInput) {
    // 1. 初始化COM环境
    HRESULT hr = CoInitialize(nullptr);
    ASSERT_EQ(S_OK, hr) << "COM环境初始化失败";

    // 2. 创建MyCom对象实例
    IMyCom* pMyCom = nullptr;
    hr = CoCreateInstance(CLSID_MyCom, nullptr, CLSCTX_ALL, IID_IMyCom, (void**)&pMyCom);
    ASSERT_NE(nullptr, pMyCom) << "无法创建MyCom对象实例";

    // 3. 构建VARIANT*参数(复用上面的代码)
    VARIANT intVar, floatVar;
    VariantInit(&intVar);
    VariantInit(&floatVar);

    V_VT(&intVar) = VT_I4;
    V_I4(&intVar) = 2;

    V_VT(&floatVar) = VT_R8;
    V_R8(&floatVar) = 0.8;

    SAFEARRAYBOUND saBound;
    saBound.cElements = 2;
    saBound.lLbound = 0;

    SAFEARRAY* pSafeArray = SafeArrayCreate(VT_VARIANT, 1, &saBound);
    ASSERT_NE(nullptr, pSafeArray) << "SAFEARRAY创建失败";

    long indices[1];
    indices[0] = 0;
    hr = SafeArrayPutElement(pSafeArray, indices, &intVar);
    ASSERT_EQ(S_OK, hr) << "写入第一个数组元素失败";

    indices[0] = 1;
    hr = SafeArrayPutElement(pSafeArray, indices, &floatVar);
    ASSERT_EQ(S_OK, hr) << "写入第二个数组元素失败";

    VARIANT arrayVar;
    VariantInit(&arrayVar);
    V_VT(&arrayVar) = VT_ARRAY | VT_VARIANT;
    V_ARRAY(&arrayVar) = pSafeArray;

    // 4. 调用Calculate函数并验证结果
    hr = pMyCom->Calculate(&arrayVar);
    ASSERT_EQ(S_OK, hr) << "Calculate函数调用失败";

    // (可选)如果Calculate有输出结果或者修改了内部状态,可以在这里添加验证逻辑
    // 比如假设Calculate计算了数组元素的总和,你可以获取结果并验证是否等于2.8

    // 5. 清理所有资源
    VariantClear(&arrayVar);
    VariantClear(&intVar);
    VariantClear(&floatVar);
    pMyCom->Release(); // 释放COM对象引用
    CoUninitialize(); // 卸载COM环境
}

几个关键注意点:

  • 资源清理:所有初始化的VARIANT都要用VariantClear清理,COM接口指针要调用Release()释放,SAFEARRAY会被VariantClear自动销毁,不用手动调用SafeArrayDestroy。
  • COM环境:在调用任何COM函数之前必须初始化COM环境(CoInitialize),用完后要卸载(CoUninitialize)。
  • 参数检查:如果Calculate函数内部没有做参数合法性检查,测试时要确保传入的VARIANT类型正确(VT_ARRAY | VT_VARIANT),避免访问非法内存。

内容的提问来源于stack exchange,提问作者JoeyWang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:08:42