Reputation: 55
I have troubles terminating _variant_t types
, it triggers a break point and the program crashes,
The part of the code causing troubles is as follows:
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, any Idea why is it causing such error? when I click "Break", it points at this inline code (comutil.h)
inline _variant_t::~_variant_t() throw()
{
::VariantClear(this);
}
Also when I click continue while debugging, the program continues with no troubles, Does that mean that I can handle that exception?
Upvotes: 1
Views: 319
Reputation: 139045
There are many potential issues in your code, for example, all your methods GetBackDoorTextVariable(), GetValues(), GetBackDoorVariable(), GetValue() could build a bad variant.
However, one thing that doesn't seem ok whatsoever, is how you handle the CorrelationNames
instance.
Because _variant_t
is an automatic wrapper classes and handles memory releases for you, you're not supposed to play with it too deeply. But in your code, you free the memory that this variant holds (with a SafeArrayDestroy
call), without setting the parray
member to null. When the destructor runs, it tries to free a null pointer and crashes.
So, remove the SafeArrayDestroy(psa)
line and it should work better, at least for this issue.
Upvotes: 1