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

从_variant_t提取字符串数组:OpenDSS C++总线名称获取失败

问题解决:从OpenDSS COM接口的_variant_t中提取总线名称字符串数组

问题分析

你的核心问题有两个:

  • 电路拓扑定义错误,导致总线列表为空
  • 从_variant_t提取字符串数组的逻辑错误,错误地将SAFEARRAY中的元素当作_variant_t类型处理,而实际是BSTR数组

修复步骤

1. 修正电路拓扑的命令错误

原代码中变压器的绕组定义重复使用了wdg=1,导致第二个绕组未正确创建,总线200不会被添加到电路中。修改变压器的命令:

DSSText->Command = "New Transformer.t1 phases=3 windings=2 xhl=5";
DSSText->Command = "~ wdg=1 bus=100 conn=delta kv=115 kva=5000";
DSSText->Command = "~ wdg=2 bus=200 conn=delta kv=4.16 kva=5000"; // 将wdg=1改为wdg=2

2. 重写字符串数组提取函数

OpenDSS的GetAllBusNames()返回的是BSTR类型的一维SAFEARRAY,而非_variant_t数组。原代码错误地尝试读取_variant_t元素,导致无法正确提取字符串。修改后的提取函数如下:

std::vector<std::wstring> GetArrayOfStrings(const _variant_t& varData) 
{
    std::vector<std::wstring> result;

    try {
        // 验证输入类型是否为BSTR数组
        if ((V_VT(&varData) & (VT_ARRAY | VT_BSTR)) != (VT_ARRAY | VT_BSTR)) {
            throw _com_error(E_INVALIDARG, L"输入不是有效的BSTR数组");
        }

        SAFEARRAY* psa = V_ARRAY(&varData);
        BSTR* pData = nullptr;
        
        // 直接锁定SAFEARRAY获取数据指针,高效且避免索引问题
        HRESULT hr = SafeArrayAccessData(psa, reinterpret_cast<void**>(&pData));
        if (FAILED(hr)) {
            throw _com_error(hr);
        }

        long lLBound, lUBound;
        SafeArrayGetLBound(psa, 1, &lLBound);
        SafeArrayGetUBound(psa, 1, &lUBound);
        long elementCount = lUBound - lLBound + 1;

        // 遍历数组,将BSTR转换为wstring
        for (long i = 0; i < elementCount; ++i) {
            if (pData[i] != nullptr) {
                result.emplace_back(pData[i]);
            }
        }

        // 解锁SAFEARRAY
        SafeArrayUnaccessData(psa);
    }
    catch (const _com_error& e) {
        std::cerr << "提取字符串数组出错: " << e.ErrorMessage() << std::endl;
    }

    return result;
}

关键改进点

  • 直接读取SAFEARRAY中的BSTR元素,跳过不必要的_variant_t中转
  • 使用SafeArrayAccessData/SafeArrayUnaccessData直接操作数组指针,比循环调用SafeArrayGetElement更高效
  • 添加类型校验,确保输入是预期的BSTR数组

测试验证

修改后运行代码,GetAllBusNames()应该返回包含100、200、300的总线名称列表,提取后的向量会正确输出这些名称。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 20:53:16