Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13

Discussione: [c++ MFC]SAFEARRAY

  1. #1
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826

    [c++ MFC]SAFEARRAY

    ciao.
    ho il seguente codice:
    codice:
    for (l=l;l < ((pSA->rgsabound[0]).cElements + (pSA->rgsabound[0]).lLbound); l++) { 
    		WCHAR *tmpArr;
    		HRESULT hr = S_OK;
    		lcount = l;
    		hr = SafeArrayGetElement(pSA,lcount,(void *)&tmpArr);
    		CString str=CString(tmpArr);
    		if(!containsElement(pArray,str) && str != "")
    			pArray->Add(str);		
    		
    	}
    tutte le volte che esegue questa istruzione:

    hr = SafeArrayGetElement(pSA,lcount,(void *)&tmpArr);
    l mi va a 0 e non capisco perchè , penso che sia un problema di puntatori , in quanto è come se la memoria puntata da lcount è la stessa di l ,per via di questa istrzione:

    lcount = l;

    ,non riesco a capir perchè.

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Ma lcount cosa e' ?

    Comunque mi sembra che il secondo argomento si debba passare per puntatore

    hr = SafeArrayGetElement(pSA, &lcount, (void *)&tmpArr);
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    si , va passato per puntatore , solo che il problema è che quando lo passo per puntatore la funzione me lo setta a 0 e non so come uscire dal ciclo.

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Mi sa che l'ultimo parametro non e' corretto ...

    Devi passare il puntatore all'area dell'elemento da restituire ... ma tu passi un puntatore ad un puntatore ... ecco perche' viene sporcata la zona di memoria seguente (e quindi la lcount) ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    il problema è che se cambio il parametro
    cosi'
    hr = SafeArrayGetElement(pSA,&l,(void **)tmpArr);
    o cosi:
    hr = SafeArrayGetElement(pSA,&l,(void *)tmpArr);


    hr mi ritorna un errore di E_INVALIDARG...

    questa è la definizone della funzione in msdn e non riesco a capire:

    HRESULT SafeArrayGetElement(
    SAFEARRAY * psa,
    long * rgIndices,
    void * pv
    );
    Parameters
    psa
    Pointer to an array descriptor created by SafeArrayCreate.
    rgIndices
    Pointer to a vector of indexes for each dimension of the array. The right-most (least significant) dimension is rgIndices[0]. The left-most dimension is stored at rgIndices[psa->cDims – 1].
    pv
    Pointer to the location to place the element of the array.
    Comments
    This function calls SafeArrayLock and SafeArrayUnlock automatically, before and after retrieving the element. The caller must provide a storage area of the correct size to receive the data. If the data element is a string, object, or variant, the function copies the element in the correct way.

    se faccio cosi' :

    for (long l = (pSA->rgsabound[0]).lLbound; l < ((pSA->rgsabound[0]).cElements + (pSA->rgsabound[0]).lLbound); l++) {
    WCHAR *tmpArr;
    HRESULT hr = S_OK;
    long rg = 0;
    hr = SafeArrayGetElement(pSA,&rg,(void *)&tmpArr);
    CString str=CString(tmpArr);
    if(!containsElement(pArray,str) && str != "")
    pArray->Add(str);
    SysFreeString(tmpArr);
    }

    hr ritorna un errore
    DISP_E_BADINDEX
    cosa puo' essere?

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Ma questo array, che tipo di elementi contiene?

    Come e' organizzato?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    è definito cosi:

    SAFEARRAYBOUND aDim[1]; // a one dimensional array
    aDim[0].lLbound= 0; //arrays start with index 0
    aDim[0].cElements= 1;

    SAFEARRAY* pSAListNamesections = SafeArrayCreate(VT_VARIANT, 1, aDim);

    e viene riempito da una chiamata ad un oggetto com che restituisce delle stringhe:
    questa è la definizione:

    Syntax
    SapObject.SapModel.PropFrame.GetNameList

    VB6 Procedure
    Function GetNameList(ByRef NumberNames As Long, ByRef MyName() As String, Optional ByVal PropType As eFramePropType) As Long

    Parameters
    NumberNames

    The number of frame section property names retrieved by the program.

    MyName

    This is a one-dimensional array of frame section property names. The MyName array is created as a dynamic, zero-based, array by the API user:

    Dim MyName() as String

    The array is dimensioned to (NumberNames - 1) inside the SAP2000 program, filled with the names, and returned to the API user.

    e lo carico cosi:
    m_pSapModel->PropFrame->GetNameList(&pNumberNames, &pSAListNamesections,SAP2000::SECTION_RECTANGULAR) ;


    in pSAListNamesections ci sono le mie stringhe

  8. #8
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    usando questo codice le stringhe vengono lette correttamente :
    HRESULT hr = S_OK;
    for (long l = (pSA->rgsabound[0]).lLbound; l < ((pSA->rgsabound[0]).cElements + (pSA->rgsabound[0]).lLbound); l++)
    {
    long rg =0;
    WCHAR *ptmpArr;
    HRESULT hr = S_OK;
    hr = SafeArrayGetElement(pSA,&rg,(void *)&ptmpArr);
    if(hr == S_OK)
    {
    CString str=CString(ptmpArr);
    if(!containsElement(pArray,str) && str != "")
    pArray->Add(str);

    }
    SysFreeString(ptmpArr);

    }
    solo che a volte mi ritorna un errore ,questo:
    Run-Time Check Failure #2 - Stack around the variable 'ptmpArr' was corrupted.

    pensavo di aver risolto con SysFreeString , invece....

  9. #9
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    questo funziona correttamente:

    codice:
    
    	LONG lstart, lend;
    	LONG idx = -1;
    	LONG nPos;
    	HRESULT hr;
    	BSTR* pbstr;
    
    	hr = SafeArrayGetLBound( sa, 1, &lstart );
    	
    	if(FAILED(hr)) return ;
    		hr = SafeArrayGetUBound( sa, 1, &lend );
    	if(FAILED(hr)) return ;
    
    	hr = SafeArrayAccessData(sa,(void HUGEP**)&pbstr);
    	if(SUCCEEDED(hr))
    	{
    		for(idx=lstart; idx <= lend; idx++)
    		{		
    			CComBSTR s;
    			s = pbstr[idx];
    			if(!containsElement(pArray,s.Copy()) && s != "")
    				pArray->Add(s.Copy());	
    		
    		}
    		hr = SafeArrayUnaccessData(sa);	
    		if(FAILED(hr)) return ;
    	}	
    	else
    		return ;

    solo che non ho capito cosa fa questa riga:
    hr = SafeArrayAccessData(sa,(void HUGEP**)&pbstr);
    cos è HUGEP?
    Grazie.

  10. #10
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    SafeArrayAccessData permette di accedere ai dati tramite un puntatore ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.