Condividi tramite


Procedura: effettuare il marshalling di matrici utilizzando l'interoperabilità C++

Aggiornamento: novembre 2007

In questo argomento viene illustrato un facet di interoperabilità Visual C++. Per ulteriori informazioni, vedere Utilizzo delle funzionalità di interoperabilità C++ (PInvoke implicito).

Negli esempi di codice riportati di seguito vengono utilizzate le direttive #pragma managed, unmanaged per implementare funzioni gestite e non gestite nello stesso file. Queste funzioni, tuttavia, vengono eseguite nello stesso modo anche se definite in file diversi. I file che contengono soltanto funzioni non gestite non richiedono necessariamente la compilazione con /clr (Compilazione Common Language Runtime).

Esempio

Nell'esempio riportato di seguito viene illustrato come passare una matrice gestita a una funzione non gestita. La funzione gestita utilizza pin_ptr per disattivare la Garbage Collection per la matrice prima di chiamare la funzione non gestita. Fornendo alla funzione non gestita un puntatore bloccato nell'heap GC, è possibile evitare il sovraccarico legato alla creazione di una copia della matrice. Per dimostrare che la funzione non gestita sta accedendo alla memoria heap GC, le modifiche apportate al contenuto della matrice vengono applicate alla funzione gestita nel momento in cui riprende il controllo.

// PassArray1.cpp
// compile with: /clr
#ifndef _CRT_RAND_S
#define _CRT_RAND_S
#endif

#include <iostream>
#include <stdlib.h>
using namespace std;

using namespace System;

#pragma unmanaged

void TakesAnArray(int* a, int c) {
   cout << "(unmanaged) array recieved:\n";
   for (int i=0; i<c; i++)
      cout << "a[" << i << "] = " << a[i] << "\n";

   unsigned int number;
   errno_t err;

   cout << "(unmanaged) modifying array contents...\n";
   for (int i=0; i<c; i++) {
      err = rand_s( &number );
      if ( err == 0 )
         a[i] = number % 100;
   }
}

#pragma managed

int main() {
   array<int>^ nums = gcnew array<int>(5);

   nums[0] = 0;
   nums[1] = 1;
   nums[2] = 2;
   nums[3] = 3;
   nums[4] = 4;

   Console::WriteLine("(managed) array created:");
   for (int i=0; i<5; i++)
      Console::WriteLine("a[{0}] = {1}", i, nums[i]);

   pin_ptr<int> pp = &nums[0];
   TakesAnArray(pp, 5);

   Console::WriteLine("(managed) contents:");
   for (int i=0; i<5; i++)
      Console::WriteLine("a[{0}] = {1}", i, nums[i]);
}

Nell'esempio riportato di seguito viene illustrato come passare una matrice non gestita a una funzione gestita. Anziché creare una matrice gestita e copiare il relativo contenuto, la funzione gestita accede direttamente alla memoria della matrice. In questo modo, le modifiche apportate dalla funzione gestita possono essere applicate anche nella funzione non gestita nel momento in cui riprende il controllo.

// PassArray2.cpp
// compile with: /clr 
#include <iostream>
using namespace std;

using namespace System;

#pragma managed

void ManagedTakesAnArray(int* a, int c) {
   Console::WriteLine("(managed) array recieved:");
   for (int i=0; i<c; i++)
      Console::WriteLine("a[{0}] = {1}", i, a[i]);

   cout << "(managed) modifying array contents...\n";
   Random^ r = gcnew Random(DateTime::Now.Second);
   for (int i=0; i<c; i++)
      a[i] = r->Next(100);
}

#pragma unmanaged

void NativeFunc() {
   int nums[5] = { 0, 1, 2, 3, 4 };

   printf_s("(unmanaged) array created:\n");
   for (int i=0; i<5; i++)
      printf_s("a[%d] = %d\n", i, nums[i]);

   ManagedTakesAnArray(nums, 5);

   printf_s("(ummanaged) contents:\n");
   for (int i=0; i<5; i++)
      printf_s("a[%d] = %d\n", i, nums[i]);
}

#pragma managed

int main() {
   NativeFunc();
}

Vedere anche

Riferimenti

Utilizzo delle funzionalità di interoperabilità C++ (PInvoke implicito)