2010-09-16 13 views

Odpowiedz

23

Poniżej znajduje się kod, aby utworzyć safearray w C++.

#include<oaidl.h> 

void CreateSafeArray(SAFEARRAY** saData)   
{ 
    double data[10]; // some sample data to write into the created safearray 
    SAFEARRAYBOUND Bound; 
    Bound.lLbound = 0; 
    Bound.cElements = 10; 

    *saData = SafeArrayCreate(VT_R8, 1, &Bound); 

    double HUGEP *pdFreq; 
    HRESULT hr = SafeArrayAccessData(*saData, (void HUGEP* FAR*)&pdFreq); 
    if (SUCCEEDED(hr)) 
    { 
      // copy sample values from data[] to this safearray 
     for (DWORD i = 0; i < 10; i++) 
     { 
      *pdFreq++ = data[i]; 
     } 
     SafeArrayUnaccessData(*saData); 
    } 
} 

Bezpłatne wskaźnik kiedy skończysz jak na poniższym Code

SAFEARRAY* saData; 
    CreateSafeArray(&saData); // Create the safe array 
    // use the safearray 
    ... 
    ... 

    // Call the SafeArrayDestroy to destroy the safearray 
    SafeArrayDestroy(saData); 
    saData = NULL; // set the pointer to NULL 

Jeśli używasz ATL dla C++, to lepsze wykorzystanie CComSafeArray zadeklarowanej w "atlsafe.h". To jest opakowanie dla SAFEARRAY. link text

+0

Wielki kodu, dobrze powiedziane. – Contango

+0

Ten artykuł bardzo mi pomógł. Dzięki. Ale użycie tej funkcji pozostawiło mnie z pustym saData-Pointer. – Teetrinker

+0

@Teetrinker - saData będzie pusta po wywołaniu SafeArrayDestroy. Dodałem komentarze do mojego kodu. – Liton

6

Kontynuując na odpowiedź @ Liton, chcę podkreślić jego ostatnie zdanie, tj. ATL CComSafeArray. To naprawdę może zaoszczędzić sporo pisania. CComSafeArray ma konstruktory C++, destruktory, przeciążenia operatorów, w tym jeden dla [], który daje odniesienie do odczytu/zapisu do dowolnego elementu w SAFEARRAY. W skrócie, można naprawdę skupić się na logice biznesowej i nie trzeba się martwić o SAFEARRAY kanalizacji:

#include <atlbase.h> 
#include <atlsafe.h> 
// ... 

    CComSafeArray<double> arr(10); 
    arr[0] = 2.0; 
    arr[1] = 3.0; 
    arr[2] = 5.0; 
    // ... 

Przynajmniej, nawet jeśli nie zamierzasz używać CComSafeArray To warto dekonstrukcji jego kod źródłowy w <atlsafe.h> daje lepszy wgląd w to, co, kiedy, dlaczego i jak na funkcje SAFEARRAY.

2

Przekazywanie SAFEARRAY nie jest zalecane. Zaleca się umieszczenie SAFEARRAY w WARIANTIE. Ponadto SAFEARRAY powinien zawierać dane VARIANT. Daje to najlepsze z wszystkich światów i sprawia, że ​​przekazanie WARIANTÓW BEZPIECZNEGO WARIANTÓW jest bardziej użyteczne dla innych języków. Na przykład. C++ do VB/C# (Uwaga to do osoby dzwoniącej do free/zniszczyć SAFEARRAY)

Opierając się na poprzednim kodzie

// A VARIANT holding a SAFEARRAY of VARIANTs 
VARIANT vRet; 

SAFEARRAYBOUND Bound; 
Bound.lLbound = 0; 
Bound.cElements = 10; 

SAFEARRAY * psaData = SafeArrayCreate(VT_VARIANT, 1, &Bound); 

VARIANT HUGEP * pData = NULL; 
HRESULT hr = SafeArrayAccessData(psaData, (void HUGEP * FAR *)&pData); 
if (SUCCEEDED(hr)) 
{ 
    for (short i = 0; i < 10; ++i,++pData) 
    { 
     ::VariantInit(pData); 
     pData->vt = VT_I2; 
     pData->iVal = i; 
    } 

    SafeArrayUnaccessData(psaData); 
} 

vRet.vt = VT_ARRAY | VT_VARIANT; 
vRet.parray = psaData; 
Powiązane problemy