Gewusst wie: Marshallen von eingebetteten Zeigern mit C++-Interop

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

Im folgenden Beispiel wird veranschaulicht, wie eine nicht verwaltete Funktion, die eine Struktur mit Zeigern verwendet, aus einer verwalteten Funktion aufgerufen werden kann. Die verwaltete Funktion erstellt eine Instanz der Struktur und initialisiert den eingebetteten Zeiger mit dem neuen Schlüsselwort (keyword) (anstelle des neuen, gcnew-Schlüsselwort (keyword)). Da dadurch der Speicher auf dem systemeigenen Heap zugewiesen wird, muss das Array nicht angeheftet werden, um die Garbage Collection zu unterdrücken. Der Speicher muss jedoch explizit gelöscht werden, um Speicherlecks zu vermeiden.

// marshal_embedded_pointer.cpp
// compile with: /clr
#include <iostream>

using namespace System;
using namespace System::Runtime::InteropServices;

// unmanaged struct
struct ListStruct {
   int count;
   double* item;
};

#pragma unmanaged

void UnmanagedTakesListStruct(ListStruct list) {
   printf_s("[unmanaged] count = %d\n", list.count);
   for (int i=0; i<list.count; i++)
      printf_s("array[%d] = %f\n", i, list.item[i]);
}

#pragma managed

int main() {
   ListStruct list;
   list.count = 10;
   list.item = new double[list.count];

   Console::WriteLine("[managed] count = {0}", list.count);
   Random^ r = gcnew Random(0);
   for (int i=0; i<list.count; i++) {
      list.item[i] = r->NextDouble() * 100.0;
      Console::WriteLine("array[{0}] = {1}", i, list.item[i]);
   }

   UnmanagedTakesListStruct( list );
   delete list.item;
}
[managed] count = 10
array[0] = 72.624326996796
array[1] = 81.7325359590969
array[2] = 76.8022689394663
array[3] = 55.8161191436537
array[4] = 20.6033154021033
array[5] = 55.8884794618415
array[6] = 90.6027066011926
array[7] = 44.2177873310716
array[8] = 97.754975314138
array[9] = 27.370445768987
[unmanaged] count = 10
array[0] = 72.624327
array[1] = 81.732536
array[2] = 76.802269
array[3] = 55.816119
array[4] = 20.603315
array[5] = 55.888479
array[6] = 90.602707
array[7] = 44.217787
array[8] = 97.754975
array[9] = 27.370446

Siehe auch

Verwenden von C++-Interop (implizites PInvoke)