Comment : marshaler des chaînes COM à l'aide de l'interopérabilité C++
Cette rubrique montre comment un BSTR (format de chaîne de base privilégié dans la programmation COM) peut être passé d’une fonction managée à une fonction non managée, et vice versa. Pour interagir avec d’autres types de chaînes, consultez les rubriques suivantes :
Guide pratique pour marshaler des chaînes Unicode à l’aide de l’interopérabilité C++
Guide pratique pour marshaler des chaînes ANSI à l’aide de l’interopérabilité C++
Les exemples de code suivants utilisent les directives de #pragma managées non managées 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 distincts. Les fichiers contenant uniquement les fonctions non managées n’ont pas besoin d’être compilés avec /clr (Compilation Common Language Runtime).
Exemple : Passer BSTR d’une fonction managée à une fonction non managée
L’exemple suivant montre comment un BSTR (format de chaîne utilisé dans la programmation COM) peut être passé d’une fonction managée à une fonction non managée. La fonction managée appelante utilise StringToBSTR pour obtenir l’adresse d’une représentation BSTR du contenu d’un .NET System.String. Ce pointeur est épinglé à l’aide de pin_ptr (C++/CLI) pour vous assurer que son adresse physique n’est pas modifiée pendant un cycle de garbage collection pendant l’exécution de la fonction non managée. Le garbage collector est interdit de déplacer la mémoire jusqu’à ce que le pin_ptr (C++/CLI) sorte de l’étendue.
// MarshalBSTR1.cpp
// compile with: /clr
#define WINVER 0x0502
#define _AFXDLL
#include <afxwin.h>
#include <iostream>
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma unmanaged
void NativeTakesAString(BSTR bstr) {
printf_s("%S", bstr);
}
#pragma managed
int main() {
String^ s = "test string";
IntPtr ip = Marshal::StringToBSTR(s);
BSTR bs = static_cast<BSTR>(ip.ToPointer());
pin_ptr<BSTR> b = &bs;
NativeTakesAString( bs );
Marshal::FreeBSTR(ip);
}
Exemple : Passer BSTR d’une fonction non managée à une fonction managée
L’exemple suivant montre comment un BSTR peut être passé d’une fonction managée à une fonction managée. La fonction managée de réception peut utiliser la chaîne en tant que BSTR ou l’utiliser PtrToStringBSTR pour la convertir en fonction d’une String utilisation avec d’autres fonctions managées. Étant donné que la mémoire représentant la BSTR est allouée sur le tas non managé, aucune épinglage n’est nécessaire, car il n’y a pas de garbage collection sur le tas non managé.
// MarshalBSTR2.cpp
// compile with: /clr
#define WINVER 0x0502
#define _AFXDLL
#include <afxwin.h>
#include <iostream>
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma managed
void ManagedTakesAString(BSTR bstr) {
String^ s = Marshal::PtrToStringBSTR(static_cast<IntPtr>(bstr));
Console::WriteLine("(managed) convered BSTR to String: '{0}'", s);
}
#pragma unmanaged
void UnManagedFunc() {
BSTR bs = SysAllocString(L"test string");
printf_s("(unmanaged) passing BSTR to managed func...\n");
ManagedTakesAString(bs);
}
#pragma managed
int main() {
UnManagedFunc();
}