Comment : marshaler des chaînes ANSI à l'aide de l'interopérabilité C++
Cette rubrique montre comment les chaînes ANSI peuvent être passées à l'aide de C++ Interop, mais le String du .NET Framework représente des chaînes au format Unicode. Par conséquent, une étape supplémentaire est requise pour la conversion au format ANSI. Pour interagir avec d'autres types de chaînes, consultez les rubriques suivantes :
Comment : marshaler des chaînes Unicode à l'aide de l'interopérabilité C++
Comment : marshaler des chaînes COM à l'aide de l'interopérabilité C++
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. Comme les fichiers qui contiennent uniquement des fonctions non managées ne doivent pas être compilés avec /clr (Compilation pour le Common Language Runtime), ils peuvent conserver leurs caractéristiques de performances.
Exemple
Cet exemple illustre le passage d'une chaîne ANSI d'une fonction managée à une fonction non managée à l'aide de StringToHGlobalAnsi. Cette méthode alloue de la mémoire sur le tas non managé et retourne l'adresse une fois la conversion exécutée. Cela signifie qu'aucun épinglage n'est nécessaire (car la mémoire sur le tas GC n'est pas passée à la fonction non managée) et que la valeur IntPtr retournée par StringToHGlobalAnsi doit être libérée explicitement sous peine d'entraîner une fuite de mémoire.
// MarshalANSI1.cpp
// compile with: /clr
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma unmanaged
void NativeTakesAString(const char* p) {
printf_s("(native) received '%s'\n", p);
}
#pragma managed
int main() {
String^ s = gcnew String("sample string");
IntPtr ip = Marshal::StringToHGlobalAnsi(s);
const char* str = static_cast<const char*>(ip.ToPointer());
Console::WriteLine("(managed) passing string...");
NativeTakesAString( str );
Marshal::FreeHGlobal( ip );
}
L'exemple suivant illustre le marshaling de données nécessaire pour accéder à une chaîne ANSI dans une fonction managée appelée par une fonction non managée. Lors de la réception de la chaîne native, la fonction managée peut l'utiliser directement ou la convertir en chaîne managée à l'aide de la méthode PtrToStringAnsi, comme indiqué.
// MarshalANSI2.cpp
// compile with: /clr
#include <iostream>
#include <vcclr.h>
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma managed
void ManagedStringFunc(char* s) {
String^ ms = Marshal::PtrToStringAnsi(static_cast<IntPtr>(s));
Console::WriteLine("(managed): received '{0}'", ms);
}
#pragma unmanaged
void NativeProvidesAString() {
cout << "(native) calling managed func...\n";
ManagedStringFunc("test string");
}
#pragma managed
int main() {
NativeProvidesAString();
}