我使用 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
文档,这是一个字符串数组
您对
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...
}