Gewusst wie: Marshallen von eingebetteten Zeigern mit C++-Interop
In den folgenden Codebeispielen werden die managed, unmanaged-#pragma-Direktiven verwendet, um verwaltete und nicht verwaltete Funktionen in derselben Datei zu implementieren. Diese Funktionen arbeiten jedoch auf dieselbe Weise zusammen, wenn sie in separaten Dateien definiert werden. Dateien, die ausschließlich nicht verwaltete Funktionen enthalten, müssen nicht mit /clr (Common Language Runtime-Kompilierung) kompiliert werden.
Beispiel
Im folgenden Beispiel wird dargestellt, wie eine nicht verwaltete Funktion, die eine Zeiger enthaltende Struktur akzeptiert, durch eine verwaltete Funktion aufgerufen werden kann. Durch die verwaltete Funktion wird eine Instanz der Struktur erstellt und ein eingebetteter Zeiger mit dem neuen Schlüsselwort initialisiert (anstelle des gcnew-Schlüsselworts). Dadurch wird der Speicher auf dem systemeigenen Heap belegt, und aus diesem Grund ist es nicht erforderlich, das Array für die unterdrückte Garbage Collection zu fixieren. Der Arbeitsspeicher muss jedoch explizit gelöscht werden, um Memory Leakage 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;
}