从 _variant_t 中提取字符串数组

问题描述 投票:0回答:1

我使用 OpenDSS 和 C++ 来运行能流。我已经建立了从 C++ 到 OpenDSS 的 COM 接口。

在 OpenDSS 的文档中,它说可以通过返回包含总线名称的字符串数组的函数调用来获取总线名称列表。返回参数的数据类型是

_variant_t
,所以我必须使用自己的函数提取字符串数组。我尝试了很多方法,但似乎都不起作用。我已附上 C++ 文件以供参考。

在这里,我总是得到这样的结果:向量是空的,而它应该包含作为公共汽车名称的字符串列表。

main 包含创建电路的部分。

GetArrayOfStrings()
是创建电路后提取数组的函数。

#import "C:\Program Files\OpenDSS\x64\OpenDSSengine.dll"
#include <Windows.h>
#include <iostream>
#include <comutil.h>
#include <vector>
#include "tchar.h"
#include "CaseSelect.h"

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

    try {
        // Extract the array from _variant_t
        SAFEARRAY* psa = V_ARRAY(&varData);

        // Get the lower and upper bounds of the array
        long lLBound, lUBound;
        SafeArrayGetLBound(psa, 1, &lLBound);
        SafeArrayGetUBound(psa, 1, &lUBound);

        // Iterate through the array
        for (long i = lLBound; i <= lUBound; ++i) {
            // Variable to store each element
            _variant_t element;

            // Get the element at index i
            SafeArrayGetElement(psa, &i, &element);

            // Convert the element to a string and add it to the result vector
            result.push_back(static_cast<const wchar_t*>(_bstr_t(element)));
        }
    }
    catch (const _com_error& e) {
        // Handle the extraction error
        // e.g., print an error message or throw an exception
        // You might also want to log more details about the error for debugging
        std::cout << "Error" << std::endl;
        //throw std::runtime_error("Error extracting array of strings: " + std::string(e.ErrorMessage()));
    }

    return result;
}

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitialize(NULL);
    try
    {
        OpenDSSengine::IDSSPtr DSSObj;
        DSSObj.CreateInstance(uuidof(OpenDSSengine::DSS));
        OpenDSSengine::ITextPtr DSSText;
        OpenDSSengine::ICircuitPtr DSSCircuit;
        OpenDSSengine::ISolutionPtr DSSSolution;
        if (DSSObj->Start(0))
        {
            cout << "OpenDSS Loaded" << endl;
            DSSText = DSSObj->Text;
            DSSCircuit = DSSObj->ActiveCircuit;
            DSSSolution = DSSCircuit->Solution;
            cout << DSSObj->Version << endl;
            DSSText->Command = "Clear";
            DSSText->Command = "New Circuit.TheveninEquivalent basekv=115 bus1=100";
            //std::vector<unsigned short> Y_matrix = DSSCircuit->SystemY;
            //DSSCircuit->SetActiveElement("Circuit.TheveninEquivalent");
            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=1 bus=200 conn=delta kv=4.16 kva=5000";
            DSSText->Command = "New Line.Ln phases=2 bus1=200.1.2 bus2=300.1.2 length=0.3 units=km";
            DSSText->Command = "~ rmatrix = (0.8261 | 0.1284 0.8226)";
            DSSText->Command = "~ xmatrix = (0.8370 | 0.2853 0.8431)";
            DSSText->Command = "~ cmatrix = (7.7626 | -1.4833 7.6902)";
            DSSSolution->Solve();
            DSSText->Command = "Show Y";
            //auto busindex = DSSCircuit->SetActiveBus("200.1.2");
            _variant_t varData = DSSCircuit->GetAllBusNames();
            try {
                std::vector<std::wstring> strings = GetArrayOfStrings(varData);

                // Now 'strings' contains the array of strings
                for (const auto& str : strings) {
                    std::wcout << str << std::endl;
                }
            }
            catch (const std::exception& ex) 
            {
                // Handle the exception
                std::cerr << "Exception: " << ex.what() << std::endl;
            }

            //DSSText->Command = "New Transformer.t1 phases=3 windings=2 xhl=5";
        };
    }
    catch (_com_error e)
    {
        printf("\n");
        printf("Error: %S\n", e.Description());
        printf("Error: %S\n", e.ErrorMessage());
    }
}

varData.vt
的十进制值为 8200,十六进制为 0x2008,根据 MSDN 中的
VARENUM
文档,这是一个字符串数组

c++ com simulation
1个回答
0
投票

您对

SafeArrayGetElement()
的使用是错误的。除了缺乏错误检查之外,您还从
BSTR
数组中获取一个元素,因此您需要将每个值直接接收到
_bstr_t
,而不是
variant_t

_bstr_t element;
if (SUCCEEDED(SafeArrayGetElement(psa, &i, element.GetAddress())) {
    result.push_back(static_cast<const wchar_t*>(element));
}
else {
    // error handling...
}
© www.soinside.com 2019 - 2024. All rights reserved.