如何使用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
相关产品推荐
相关产品推荐

