Comment créer et initialiser SAFEARRAY des doubles en C ++ pour passer en C #

Ma méthode C # doit être appelée à partir de C ++

A l’origine, ma méthode C # prend un paramètre de type double [], mais en appelant depuis C ++, elle devient un SAFEARRAY

En C ++, je dois prendre des données d’un tableau de doublons et remplir un fichier SAFEARRAY. Je n’ai trouvé aucun exemple de code pour le faire.

Toute aide est appréciée

Voici le code pour créer un safearray en C ++.

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

Libérez le pointeur lorsque vous avez terminé, comme dans le code suivant.

  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 

Si vous utilisez ATL pour C ++, utilisez plutôt CComSafeArray déclaré dans "atlsafe.h". C'est wrapper pour SAFEARRAY. lien texte

Poursuivant la réponse de @ Liton, je voudrais insister sur sa dernière phrase, à savoir CComSafeArray d’ATL. Cela peut vraiment vous épargner beaucoup de frappe. CComSafeArray a des constructeurs C ++, des destructeurs, des surcharges d’opérateurs, dont un pour [] qui vous donne une référence en lecture / écriture sur n’importe quel élément du SAFEARRAY . En bref, vous pouvez vraiment vous concentrer sur votre logique métier sans avoir à vous soucier de la plomberie SAFEARRAY :

 #include  #include  // ... CComSafeArray arr(10); arr[0] = 2.0; arr[1] = 3.0; arr[2] = 5.0; // ... 

À tout le moins, même si vous n’utilisez pas CComSafeArray il vaut la peine de déconstruire son code source dans pour vous donner un meilleur aperçu des fonctions Quoi, Quand, Pourquoi et Comment SAFEARRAY .

Passer SAFEARRAY n’est pas recommandé. Il est recommandé de placer le SAFEARRAY dans un VARIANT. En outre, le SAFEARRAY devrait contenir des données VARIANT. Cela donne le meilleur des mondes et rend le passage de SAVARIANT VARIANT de VARIANT plus utile à d’autres langues. Par exemple, C ++ vers VB / C # (notez que c’est à l’appelant de libérer / détruire le SAFEARRAY)

Construire sur le code précédent

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