Gewusst wie: Marshallen von Arrays mit C++-Interop

In diesem Thema wird ein Facet der Visual C++-Interoperabilität veranschaulicht. Weitere Informationen finden Sie unter Using C++ Interop (Implicit PInvoke).

In den folgenden Codebeispielen werden die verwalteten, nicht verwalteten #pragma Direktiven verwendet, um verwaltete und nicht verwaltete Funktionen in derselben Datei zu implementieren, diese Funktionen funktionieren jedoch in gleicher Weise, wenn sie in separaten Dateien definiert sind. Dateien, die nur nicht verwaltete Funktionen enthalten, müssen nicht mit /clr (Common Language Runtime Compilation) kompiliert werden.

Beispiel: Übergeben eines verwalteten Arrays an nicht verwaltete Funktion

Das folgende Beispiel veranschaulicht, wie ein verwaltetes Array an eine nicht verwaltete Funktion übergeben wird. Die verwaltete Funktion verwendet pin_ptr (C++/CLI), um die Garbage Collection für das Array zu unterdrücken, bevor die nicht verwaltete Funktion aufgerufen wird. Durch die Bereitstellung der nicht verwalteten Funktion mit einem angehefteten Zeiger in den GC-Heap kann der Aufwand beim Erstellen einer Kopie des Arrays vermieden werden. Um zu veranschaulichen, dass die nicht verwaltete Funktion auf den GC-Heap-Speicher zugreift, ändert sie den Inhalt des Arrays, und die Änderungen werden angezeigt, wenn die verwaltete Funktion die Steuerung wieder einhält.

// 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 received:\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]);
}

Beispiel: Übergeben eines nicht verwalteten Arrays an verwaltete Funktion

Das folgende Beispiel veranschaulicht das Übergeben eines nicht verwalteten Arrays an eine verwaltete Funktion. Die verwaltete Funktion greift direkt auf den Arrayspeicher zu (im Gegensatz zum Erstellen eines verwalteten Arrays und Kopieren des Arrayinhalts), wodurch Änderungen, die von der verwalteten Funktion vorgenommen wurden, in der nicht verwalteten Funktion widergespiegelt werden können, wenn sie wieder die Kontrolle erhält.

// 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 received:");
   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();
}

Siehe auch

Verwenden von C++-Interop (implizites PInvoke)