2010-09-16 5 views
10

Mein C# Methode übergeben werden muss, von C++So erstellen und SAFEARRAY von Doppel in C++ zu initialisieren, um C#

aufgerufen werden

mein C# Methode ursprünglich einen Parameter vom Typ double [] nimmt, aber wenn man von C Aufruf ++ wird es a SAFEARRAY

In C++ muss ich Daten aus einem Array von Doppel und nehmen Sie einen SAFEARRAY. Ich habe keinen Beispielcode gefunden, um dies zu tun.

Jede Hilfe sehr geschätzt wird

Antwort

23

Im Folgenden finden Sie den Code ein Safearray in C++ zu erstellen.

#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); 
    } 
} 

Freies der Zeiger, wenn Sie wie in der folgenden 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 

fertig sind Wenn Sie ATL für C++ verwenden, dann eine bessere Nutzung CComSafeArray in "atlsafe.h" erklärt. Dies ist Wrapper für SAFEARRAY.

+0

Großer Code, gut. – Contango

+0

Dieser Artikel hat mir sehr geholfen. Vielen Dank. Aber die Verwendung der Funktion ließ mich mit einem leeren saData-Pointer zurück. – Teetrinker

+0

@Teetrinker - saData wird leer sein, nachdem SafeArrayDestroy aufgerufen wurde. Ich habe dem my-Code einige Kommentare hinzugefügt. – Liton

6

Fortsetzung auf @ Liton Antwort, möchte ich seinen letzten Satz betonen, d. H. ATL CComSafeArray. Es kann Ihnen wirklich viel Tipparbeit ersparen. CComSafeArray hat C++ - Konstruktoren, Destruktoren, Operator-Überladungen einschließlich einer für [], die Ihnen eine Lese-/Schreibreferenz für jedes Element in SAFEARRAY gibt. Kurz gesagt, können Sie wirklich Ihre Geschäftslogik konzentrieren und müssen sich keine Sorgen über die SAFEARRAY Sanitär:

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

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

Am allerwenigsten, auch wenn du gehst zu CComSafeArray nicht zu verwenden, es lohnt sich, seinen Quellcode zu dekonstruieren in <atlsafe.h> gibt Ihnen einen besseren Einblick auf was, wann, warum und wie auf SAFEARRAY Funktionen.

2

Das Übergeben von SAFEARRAYs wird nicht empfohlen. Es wird empfohlen, den SAFEARRAY in eine VARIANT zu platzieren. Außerdem sollte der SAFEARRAY VARIANT-Daten enthalten. Dies ergibt das Beste aus allen Welten und macht die Übergabe von VARIANT SAFEARRAY von VARIANTs für andere Sprachen nützlicher. Z.B. C++ VB/C#, sagte (Hinweis: Es ist bis zu dem Anrufer der SAFEARRAY zu befreien/zerstören)

Aufbauend auf dem vorherigen Code

// 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;