2009-03-12 2 views
2

Ich habe folgenden CodeblockProblem mit Safearray Zugang CComVariant Verwendung

///////////////////////////////////// 
CComVariant newVal; 

//pass the CComVariant and get the strings array!!! 
GetStrList(newVal); 
USES_CONVERSION; 

if (((newVal.vt & VT_ARRAY) == VT_ARRAY) && ((newVal.vt & VT_BSTR) == VT_BSTR)) 
{ 
SAFEARRAY* paArray = newVal.parray; 
BSTR * str = NULL; 
SafeArrayAccessData(paArray, (void**)&str); 

SafeArrayUnaccessData(paArray); 

long lLBound = 0; 
long lUBound = 0; 
long nCount = 0; 

if (FAILED(SafeArrayGetLBound(paArray, 1, &lLBound)) || 
    FAILED(SafeArrayGetUBound(paArray, 1, &lUBound))) 
{ 
    ASSERT(false); 
    return FALSE; 
} 


nCount = (lUBound - lLBound + 1); 
for (int i = 0 ; i < nCount ; i++) 
{   
    m_cstrList.AddString(W2T(str[i]));     
} 
//SafeArrayDestroy(paArray); ---> is it required here??? 

} 

///////////////////////////////////// 

Verfahren die sichere Arrays ist

HRESULT GetStrList(VARIANT *pVal) 
{ 
USES_CONVERSION; 

if (!pVal) 
    return E_FAIL; 

SAFEARRAYBOUND bound[1]; //single dimension array 
bound[0].lLbound = 0; 
bound[0].cElements = 10; 

SAFEARRAY * A = SafeArrayCreate(VT_BSTR, 1, bound); 

BSTR * str = NULL; 
SafeArrayAccessData(A, (void**)&str); 

//user wants the NT view OPC drivers list. 
for (int i=0;i<10;i++) 
{  
    str[i] = SysAllocString(T2W(mystrings[i]));  
} 


VariantInit(pVal); 
pVal->vt  = VT_ARRAY | VT_BSTR; 
pVal->parray = A; 

SafeArrayUnaccessData(A); 
A = NULL; 

return S_OK; 
} 

My Zweifel returing oberhalb erster Block von Code hat keine Speicherlecks? Handelt sich die CComVariant selbst um die Reinigung? oder mache ich auch manuell SafeArrayDestroy(paArray);

Vielen Dank im Voraus!

Antwort

3

CComVariant-Destruktor ruft VariantClear() auf, was freigibt, was auch immer die Variante war, einschließlich Arrays.

Eine Einschränkung: Das Array sollte nicht zu dem Zeitpunkt gesperrt sein, wenn VariantClear() aufgerufen wird. Dies bedeutet, dass wenn eine Ausnahme nach SafeArrayAccessData() ausgelöst wird, aber vor SafeArrayUnaccessData() diese nicht aufgerufen wird und VariantClear() keine Ressourcen freigibt.

Daher schreiben Sie besser eine Klammerklasse für die Paarung von SafeArrayAccessData() - und SafeArrayUnaccessData() - Aufrufen.

+0

wenn ich SafeArrayDestroy mache (paArray); dann bekomme ich keine Abstürze. Laut Ihnen sollte CComVariant auch das gleiche Array wieder zerstören und versuchen, das bereits zerstörte Array zu zerstören. – coolcake

+0

Nun, ja. Vielleicht stürzt es nicht zufällig ab, aber MSDN sagt, dass VariantClear() nicht gesperrte Arrays freigibt. Der Versuch, sie manuell freizugeben, würde zu einer doppelten Freigabe führen, die überhaupt nicht gut ist. – sharptooth

+0

Also sollte ich nicht SafeArrayDestroy für CComVariant verwenden? – coolcake

Verwandte Themen