2016-12-01 3 views
1

У меня проблемы terminating _variant_t types, это вызывает точку останова и программные сбои,подрывающий _variant_t вызывает точку останова (C++)

Часть кода, вызывающего проблемы заключается в следующем:

double ConnectToHYSYS::GetExergy() { 

    //In this method, I'm using early Binding, so no more Dispatchs, lets get the interfaces themselves 

    int i; 
    HRESULT hr = hyStream->QueryInterface(IID_PPV_ARGS(&hyBackDoor)); 

    if (SUCCEEDED(hr)) { 
     cout << "Got the BackDoor safely" << endl; 

     // Get Array of CorrelationNames but in type _variant_t 
     _variant_t t = _variant_t("HysysCorrelation.300.[]:Name.0"); 
     InternalVariableWrapper = hyBackDoor->GetBackDoorTextVariable(&t); 
     TextFlexVariable = InternalVariableWrapper->GetVariable(); 
     _variant_t CorrelationNames= TextFlexVariable->GetValues(); 



     //Conversion of _variant_t type to safe Array 

     SAFEARRAY *psa; 
     psa = CorrelationNames.parray; 


     // Loop through safeArray of BSTR 
      BSTR* pVals; 
     HRESULT hr = SafeArrayAccessData(psa, (void**)&pVals); // direct access to SA memory 
     if(SUCCEEDED(hr)) 
     { 
      long lowerBound, upperBound; // get array bounds 
      SafeArrayGetLBound(psa, 1, &lowerBound); 
      SafeArrayGetUBound(psa, 1, &upperBound); 

      long cnt_elements = upperBound - lowerBound + 1; 
      for(i = 0; i < cnt_elements; ++i) // iterate through returned values 
      { 
       BSTR lVal = pVals[ i ]; 

       //Convert to normal String for comparison with Mass Exergy 
       string CorrelationFinal= ConvertBSTRToMBS(lVal); 
       std::cout << "element " << i << ": value = " << CorrelationFinal << std::endl; 

       if(CorrelationFinal == "Mass Exergy"){ break; } 
      } 
      SafeArrayUnaccessData(psa); 
     } 
     SafeArrayDestroy(psa); 
     if (SUCCEEDED(hr)) { 
      cout << "Got the BackDoor Text Variable safely" << endl; 
     } 

     if (FAILED(hr)) { 
      cout << "Couldnt get the BackDoor Text Variable" << endl; 
     } 
    } 

    if (FAILED(hr)) { 
     cout << "Couldnt get the BackDoor" << endl; 
    } 
// Get Exergy Moniker 
    string str = to_string(i); 
    string ExergyMoniker ="HysysCorrelation.300." + str + ":ExtraData.550.0"; 

    // OLE accepts only _variant_t type and we need char array for that conversion... converting string to char array 

    char tab2[ 1024 ]; 
    strncpy_s(tab2, ExergyMoniker.c_str(), sizeof(tab2)); 
    tab2[ sizeof(tab2) - 1 ] = 0; 

    //Get the exergy itself 

    _variant_t t = _variant_t(tab2); 
    InternalVariableWrapper = hyBackDoor->GetBackDoorVariable(&t); 
    RealVariable = InternalVariableWrapper->GetVariable(); 
    _variant_t ExergyValue = RealVariable->GetValue("kJ/kg"); 
    double ExergyValueDouble = ExergyValue.dblVal; 

    return ExergyValueDouble; 

Так , любая идея, почему она вызывает такую ​​ошибку? при нажатии кнопки «Break», он указывает на этот встроенный код (comutil.h)

inline _variant_t::~_variant_t() throw() 
{ 
    ::VariantClear(this); 
} 

Кроме того, когда я нажимаю продолжить во время отладки, программа продолжается без каких-либо проблем, значит ли это, что я могу справиться с этим исключением?

+0

Существует много потенциальных проблем (например, все ваши методы GetBackDoorTextVariable(), GetValues ​​(), GetBackDoorVariable(), GetValue() могут создать плохой вариант). Однако это может быть связано с экземпляром CorrelationNames. Поскольку _variant_t является автоматической оболочкой, вы не должны слишком сильно играть с ней. Вы можете попытаться удалить строку SafeArrayDestroy (psa), потому что то, что она делает, освобождает память за _variant_t.parray, но позволяет указателю на параметр не нулевым ... _variant_t должен освобождать память автоматически во время уничтожения. –

+0

Большое спасибо @SimonMourier !!! Работал как Магия! удаление строки SafeArrayDestroy (psa) разрешило исключение. Как я могу принять это как решение? – Peet

+0

Я построил правильный ответ –

ответ

1

В коде есть много потенциальных проблем, например, все ваши методы GetBackDoorTextVariable(), GetValues ​​(), GetBackDoorVariable(), GetValue() могут создать плохой вариант.

Однако, одна вещь, которая не выглядит нормально, заключается в том, как вы обрабатываете экземпляр CorrelationNames.

Потому что _variant_t является классом автоматической обертки и управляет выпуском памяти для вас, вы не должны играть с ним слишком глубоко. Но в вашем коде вы освобождаете память, которую имеет этот вариант (с вызовом SafeArrayDestroy), не устанавливая для элемента parray значение null. Когда деструктор работает, он пытается освободить нулевой указатель и сработает.

Итак, удалите линию SafeArrayDestroy(psa), и она должна работать лучше, по крайней мере, для этой проблемы.