2016-12-01 1 views
1

Ich habe Probleme terminating _variant_t types, löst es einen Haltepunkt, und das Programm stürzt ab,destructing _variant_t einen Haltepunkt verursacht (C++)

Der Teil des Codes Probleme verursacht, ist wie folgt:

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; 

So , irgendeine Idee, warum verursacht es solche Fehler? wenn ich „Break“ klicken, zeigt es auf diesem Inline-Code (comutil.h)

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

Auch wenn ich weiter klicken, während das Debuggen, läuft das Programm ohne Probleme, Heißt das, dass ich diese Ausnahme behandeln kann?

+0

Es gibt viele mögliche Probleme (zum Beispiel alle Ihre Methoden GetBackDoorTextVariable(), GetValues ​​(), GetBackDoorVariable(), GetValue() könnte eine schlechte Variante erstellen). Dies könnte jedoch auf die CorrelationNames-Instanz zurückzuführen sein. Da _variant_t ein automatischer Wrapper ist, sollten Sie nicht zu tief damit spielen. Sie können versuchen, die SafeArrayDestroy (psa) Linie zu entfernen, weil es macht was frei ist der Speicher hinter dem _variant_t.parray aber es lässt den pArray Zeiger nicht null ... _variant_t soll den Speicher automatisch auf die Zerstörung der Zeit befreien. –

+0

Vielen Dank @SimonMourier !!! Arbeitete wie Magie! Entfernen der SafeArrayDestroy (PSA) -Zeile löste die Ausnahme. Wie kann ich das als Lösung akzeptieren? – Peet

+0

Ich habe eine richtige Antwort gebaut –

Antwort

1

Es gibt viele mögliche Probleme in Ihrem Code, zum Beispiel alle Ihre Methoden GetBackDoorTextVariable(), GetValues ​​(), GetBackDoorVariable(), GetValue() könnte eine schlechte Variante erstellen.

jedoch eine Sache, die nicht in Ordnung, was auch immer scheint, ist, wie Sie die CorrelationNames Instanz behandeln.

Da _variant_t ist ein automatischer Wrapper Klassen und behandelt Speicher-Releases für Sie, Sie sollten nicht damit zu tief spielen. Aber in Ihrem Code befreien Sie den Speicher, der diese Variante (mit einem SafeArrayDestroy Aufruf) hält, ohne die Einstellung der parray Mitglied auf null. Wenn der Destruktor ausgeführt wird, versucht es einen Nullzeiger freizugeben und abstürzt.

So entfernen Sie die SafeArrayDestroy(psa) Linie und es sollte besser funktionieren, zumindest für dieses Problem.

Verwandte Themen