2012-09-18 21 views
10

cómo iterar a través del puntero de C++ safearray al puntero y acceder a sus elementos.Cómo iterar a través de SAFEARRAY **

Me trataron de replicar la solución publicado por Lim Bio Liong http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/022dba14-9abf-4872-9f43-f4fc05bd2602 pero lo más curioso es que la firma del método IDL viene a ser

HRESULT __stdcall GetTestStructArray([out] SAFEARRAY ** test_struct_array); 

en lugar de

HRESULT __stdcall GetTestStructArray([out] SAFEARRAY(TestStruct)* test_struct_array); 

Todas las ideas ?

gracias de antemano

+0

¿Qué es 'cmd'? ! –

Respuesta

21

Los Safearrays se crean con SafeArrayCreate o SafeArrayCreateVector, pero cuando pregunta acerca de iterar sobre un SAFEARRAY, digamos que ya tiene un SAFEARRAY devuelto por alguna otra función. Una forma es usar SafeArrayGetElement API, que es especialmente conveniente si tiene SAFEARRAY multidimensionales, ya que permite, IMO, una especificación un poco más fácil de los índices.

Sin embargo, para los vectores (SAFEARRAY unidimensional) es más rápido acceder directamente a los datos e iterar sobre los valores. Aquí hay un ejemplo:

Digamos que es un SAFEARRAY de long s, es decir. VT_I4

// get them from somewhere. (I will assume that this is done 
// in a way that you are now responsible to free the memory) 
SAFEARRAY* saValues = ... 
LONG* pVals; 
HRESULT hr = SafeArrayAccessData(saValues, (void**)&pVals); // direct access to SA memory 
if (SUCCEEDED(hr)) 
{ 
    long lowerBound, upperBound; // get array bounds 
    SafeArrayGetLBound(saValues, 1 , &lowerBound); 
    SafeArrayGetUBound(saValues, 1, &upperBound); 

    long cnt_elements = upperBound - lowerBound + 1; 
    for (int i = 0; i < cnt_elements; ++i) // iterate through returned values 
    {        
    LONG lVal = pVals[i]; 
    std::cout << "element " << i << ": value = " << lVal << std::endl; 
    }  
    SafeArrayUnaccessData(saValues); 
} 
SafeArrayDestroy(saValues); 
+5

SafeArrayDestroy() no pertenece a este código. No destruyas la matriz si no eres el propietario. –

+0

el 'get them from somewhere' tenía la intención de denotar un escenario típico de tener un método que devuelve un SAFEARRAY como parámetro' [out] 'en cuyo caso el cliente es responsable de la limpieza, pero eso podría no ser obvio. He editado la respuesta –

+0

¿Cómo accedo a Safearray cuando tengo 2 dimensiones? – savi

3

MSDN SafeArrayGetElement function le da un fragmento de código en el uso de SafeArrayGetElement obtener objeto individual a la matriz.

SAFEARRAY structure y SafeArray* funciones explican la API disponible.

En el proyecto ATL/MFC, le conviene usar clases contenedoras, p. CComSafeArray para hacer las cosas más simples y fáciles. Ver Simplifying SAFEARRAY programming with CComSafeArray en esto.

+0

Su último enlace está roto. –

+0

@SimonMourier: Gracias, reemplacé con un enlace en caché, no estoy seguro de si el contenido original no está disponible de forma permanente o temporal. –

+1

Lo encontré aquí si: https://blogs.msmvps.com/gdicanio/2011/02/04/simplifying-safearray-programming-with-ccomsafearray/ con google ayuda –

Cuestiones relacionadas