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

如何使用Softing OPC-Classic-SDK编写C++字符串数组?

解决Softing OPC-Classic-SDK字符串数组写入崩溃问题

你当前的字符串数组写入代码崩溃,核心原因是对OPC Classic中SafeArray的字符串类型处理逻辑理解错误:OPC的字符串数组对应的是BSTR类型的SafeArray,而非普通的wchar_t**指针数组,直接操作宽字符指针会破坏SafeArray的内存结构,导致访问错误。

正确的字符串数组实现代码

Variant Data;
DateTime CurrentTime;
CurrentTime.now();

size_t Size = Values.size();
// 1. 初始化Variant为数组+字符串类型(VT_ARRAY | VT_BSTR)
Data.vt = VT_ARRAY | VT_BSTR;

// 2. 创建SafeArray,指定维度为1,元素类型为VT_BSTR
SAFEARRAYBOUND bound = { static_cast<ULONG>(Size), 0 };
Data.parray = SafeArrayCreate(VT_BSTR, 1, &bound);

if (Data.parray != nullptr) {
    BSTR* ArrayVar = nullptr;
    // 3. 访问SafeArray的BSTR数组指针
    HRESULT hr = Data.SafeArrayAccessData(Data.parray, reinterpret_cast<void**>(&ArrayVar));
    if (SUCCEEDED(hr)) {
        // 4. 为每个元素分配BSTR并赋值
        for (size_t j = 0; j < Size; ++j) {
            // 使用SysAllocString分配BSTR,自动处理内存
            ArrayVar[j] = SysAllocString(Values[j].c_str());
        }
        // 5. 取消SafeArray访问
        Data.SafeArrayUnaccessData(Data.parray);
    }
}

// 后续写入逻辑和浮点数组一致
ItemValues.emplace_back(new ValueQT(Data, EnumQuality_QUALITY_NOT_SET, CurrentTime));
ItemNames.emplace_back(ItemName);
ItemPaths.emplace_back(L"");

Session->write(ItemNames, ItemPaths, const_cast<std::vector<ValueQT*>&>(ItemValues), WriteResults, &ExecutionOptions_);

关键注意事项

  • 必须将Variant的类型设置为VT_ARRAY | VT_BSTR,明确这是BSTR类型的数组
  • 使用SafeArrayCreate创建符合要求的SafeArray,元素类型指定为VT_BSTR
  • 字符串必须通过SysAllocString分配为BSTR,不能直接拷贝普通宽字符指针,因为BSTR有特定的内存管理机制
  • 确保在访问SafeArray后调用SafeArrayUnaccessData,完成内存同步
  • 不需要手动释放BSTR:SafeArray会在Variant销毁时自动释放所有内部的BSTR资源

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:46:16