Comment : marshaler des tableaux à l'aide de l'interopérabilité C++
Cette rubrique illustre une facette de l'interopérabilité Visual C++. Pour plus d'informations, consultez Utilisation de l'interopérabilité C++ (PInvoke implicite).
Les exemples de code suivants utilisent les directives #pragma managed, unmanaged pour implémenter des fonctions managées et non managées dans le même fichier, mais ces fonctions interagissent de la même manière si elles sont définies dans des fichiers séparés. Les fichiers qui contiennent uniquement des fonctions non managées ne doivent pas être compilés avec /clr (Compilation pour le Common Language Runtime).
Exemple
L'exemple suivant montre comment passer un tableau managé à une fonction non managée. La fonction managée utilise pin_ptr afin de supprimer le garbage collection pour le tableau avant d'appeler la fonction non managée. En fournissant la fonction non managée avec un pointeur épinglé dans le tas GC, la charge mémoire entraînée par la réalisation d'une copie du tableau peut être évitée. Pour montrer que la fonction non managée accède à la mémoire de tas GC, elle modifie le contenu du tableau et les modifications sont reflétées lorsque la fonction managée reprend le contrôle.
// 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]);
}
L'exemple suivant illustre le passage d'un tableau non managé à une fonction managée. La fonction managée accède directement à la mémoire du tableau (plutôt que de créer un tableau managé et de copier son contenu), permettant ainsi de répercuter les modifications apportées par la fonction managée dans la fonction non managée lorsqu'elle reprend le contrôle.
// 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();
}