VARIANT Variable mit String füllen



  • Hallo Gast,

    ein Variantarray kannst Du so auslesen, zum Verständnis, ein
    Variant ist eine Union die eigentlich ein DWORD unter verschiedenen
    Datentypen ablichtet, das kann auch ein Zeiger auf Text oder sonnst was
    sein :

    Beispiel einer varianten initialisierung:
    VARIANT var;
    var.vt_type = VT_INT;
    var.val = 4711

    CComVariant covar(var); //der ComVariant initalisiert sich nun selbst als int
    das geht Dito für Text und auch mit CStringList.

    Pseudocode! bezüglich variantlist

    HRESULT tracevarlst(VARIANT varSelectionList)
    {
       HRESULT hRes = S_FALSE;
    
       if(varSelectionList.vt != (VT_ARRAY | VT_VARIANT) || varSelectionList.parray == NULL)
       {
    	 return hRes;
       }
    
       CComVariant covarDescriptor;
       register SAFEARRAY * psaSelectionList = varSelectionList.parray;
       register long  Vstart = psaSelectionList->rgsabound->lLbound;
       register long  Vcnt   = psaSelectionList->rgsabound->cElements;
    
       for(register long i=Vstart; i < Vstart+Vcnt; i++)
       {
    		hRes = SafeArrayGetElement(psaSelectionList, &i, &covarDescriptor);
    		if(FAILED(hRes))
    		 break;
    
    		if(covarDescriptor.vt != VT_BSTR)
    		{
    		  hRes = covarDescriptor.ChangeType(VT_BSTR);
    
    		  if(FAILED(hRes))
    		    break;
    		}
    
    		TRACE(_T("[%s],"),CString(covarDescriptor.bstrVal));
       }
    
       return hRes;
    }
    

    Hier Prinzip zum befüllen.. (ungetestet als Hinweis)

    CComVariant *andersrum(void)
    {
       TCHAR test[11][]={"1","1","1","1","1","1","1","1","1","1","1"};
       HRESULT hRes = S_FALSE;
    
       static CComVariant    covarDescriptor;//zum testen hier mal
    
       register long  start    = 0;
       register long  cnt      = 0;
    
       //Create Save Array to store results in a VARlist
       SAFEARRAYBOUND  size    = {cnt,start};//start is here null
       register SAFEARRAY      *psaResult = SafeArrayCreate(VT_VARIANT, 1, &size);
       if(psaResult == NULL)
         return hRes;
    
       for(register long n=start;n<10; n++)
       {
         size.cElements++;
    	 hRes = SafeArrayRedim(psaResult,&size);
         if(FAILED(hRes))
           break;
    
    	 covarDescriptor = CString(&test[n][0]);
    	 hRes = SafeArrayPutElement(psaResult, &n, &covarDescriptor);
    	 if(FAILED(hRes))
    	  break;			
       }
    
       if(hRes == S_OK )
       {
        VariantInit(pvarRecordValues);
    	(*pvarRecordValues).parray = psaResult;
        (*pvarRecordValues).vt = VT_ARRAY | VT_VARIANT;
       }else SafeArrayDestroy(psaResult);
    
       return &covarDescriptor;
    }
    


  • Achromat schrieb:

    ...
       for(register long i=Vstart; i < Vstart+Vcnt; i++)
       {
    		hRes = SafeArrayGetElement(psaSelectionList, &i, &covarDescriptor);
    		if(FAILED(hRes))
    		 break;
    
    		if(covarDescriptor.vt != VT_BSTR)
    		{
    		  hRes = covarDescriptor.ChangeType(VT_BSTR);
    
    		  if(FAILED(hRes))
    		    break;
    		}
    
    		TRACE(_T("[%s],"),CString(covarDescriptor.bstrVal));
       }
    ...
    

    Das leakt.
    Der 3. Parameter von SafeArrayGetElement ist "out". D.h. es wird das was da vorher dort steht blind überschrieben - OHNE Cleanup. D.h. das was vorher dort steht darf keinen Cleanup erfordern.
    VT_BSTR erfordert aber Cleanup.

    => du leakst (Vcnt - 1) BSTR s.

    Fix:
    covarDescriptor.Clear(); vor dem SafeArrayGetElement() machen.

    ps:

    Achromat schrieb:

    register long ...
    

    *facepalm*


  • Mod

    Oder covarDescriptor einfach in die Schliefe nehmen.
    Dann macht der Destruktor alles richtig.

    Der static vor covarDescriptor ist auch bedenklich. Das ganze nur um einen Zeiger zurück zugeben.
    Variants sind kopiernbar. Besser man übergibt eine Referenz oder Zeiger an die Funktion, wie das in COMeher üblich ist.



  • In dem Thread war die Frage nach Varianten listen,
    nun hat jemand unter Anmerkung des Pseudocodes diese
    dargelegt. Nun folgt die Zerlegung des Pseudocodes.
    Doch selbst gab den Hinweis keiner, das Aufmunieren
    hilfreicher Angaben, steht mehr im Vordergrund.
    Wie schade.

    Liebe Grüße.



  • @Achromat
    Wenn du es nicht schaffst korrekten Code zu posten, dann darfst du entweder nicht mehr posten, oder du musst es aushalten wenn jmd. deine Fehler korrigiert.

    Und ich finde es peinlich wenn man dann versucht sich rauszureden.
    Die Ausrede "Pseudocode" ist ja wohl das dämlichste von überhaupt. Dein Code ist kein Pseudocode, sondern einfach nur schlechter Code den du irgendwo rauskopiert und u.U. leicht angepasst/modifiziert hast.

    Ich meine, hältst du uns für total bescheuert oder was?

    So. Und jetzt liest das jmd. der es nicht schafft sich die nötigen Infos selbst zu ergoogeln. Und du meinst jetzt der kommt drauf dass dein Code leakt? Ganz sicher nicht.

    Doch selbst gab den Hinweis keiner, das Aufmunieren
    hilfreicher Angaben, steht mehr im Vordergrund.

    Geh mal zum Arzt.


  • Mod

    hustbaer schrieb:

    Doch selbst gab den Hinweis keiner, das Aufmunieren
    hilfreicher Angaben, steht mehr im Vordergrund.

    Geh mal zum Arzt.

    Ich würde mal raten und sagen: "Kahn ist zurück..."



  • Zum Arzt kahn ?

    sehr seltsames Forum hier.. viel Spass euch
    in der low Level World.



  • Achromat genau das war gesucht!



  • @Achromat
    Viel Spass beim schlechte Software entwickeln.
    Ich hoffe ich muss was du programmierst nie verwenden.



  • Das wäre doch sehr schade. Ich denke nicht das es je ein Memory Leak in meinen Versionen gibt 🙂 Und wenn freue ich mich natürlich wenn soetwas aufgedeckt wird, hier war es hingegen aus dem Handgelenk eingetippt,
    stell Dir vor da
    war mit keiner Exeption zu rechnen ^^

    Lg
    Karsten.


Anmelden zum Antworten