Практическое руководство. Упаковка встроенных указателей посредством взаимодействия C++
В следующем примере кода директивы #pragma managed, unmanaged используются для реализации управляемых и неуправляемых функций в одном файле4 однако если эти функции определены в разных файлах, они взаимодействуют так же. Файлы, содержащие только неуправляемые функции, не требуется компилировать с использованием /clr (компиляция CLR).
Пример
В следующем примере показан порядок вызова неуправляемой функции, которая принимает содержащую указатели структуру, из управляемой функции. С помощью управляемой функции создается экземпляр структуры и инициализируется встроенный указатель с использованием ключевого слова new (вместо ключевого слова gcnew). Поскольку при этом осуществляется выделение памяти в собственной куче, не требуется закреплять массив, чтобы запретить сборку мусора. Однако чтобы предотвратить утечку памяти, необходимо явно освободить память.
// 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;
}