Utilisation de l’interopérabilité C++ (PInvoke implicite)
Contrairement à d’autres langages .NET, Visual C++ prend en charge l’interopérabilité qui permet au code managé et non managé d’exister dans la même application et même dans le même fichier (avec les pragmas managés non managés ). Cela permet aux développeurs Visual C++ d’intégrer des fonctionnalités .NET dans des applications Visual C++ existantes sans déranger le reste de l’application.
Vous pouvez également appeler des fonctions non managées à partir d’une compilation managée à l’aide de dllexport, dllimport.
PInvoke implicite est utile quand vous n’avez pas besoin de spécifier la façon dont les paramètres de fonction seront marshalés, ou l’un des autres détails qui peuvent être spécifiés lors de l’appel explicite de DllImportAttribute.
Visual C++ fournit deux façons pour les fonctions managées et non managées d’interagir :
PInvoke explicite est pris en charge par le .NET Framework et est disponible dans la plupart des langages .NET. Mais comme son nom l’indique, L’interopérabilité C++ est spécifique à Visual C++.
Interopérabilité C++
L’interopérabilité C++ offre une meilleure sécurité de type et il est généralement moins fastidieux d’implémenter. Toutefois, L’interopérabilité C++ n’est pas une option si le code source non managé n’est pas disponible ou pour les projets multiplateformes.
interopérabilité C++ COM
Les fonctionnalités d’interopérabilité prises en charge par Visual C++ offrent un avantage particulier sur d’autres langages .NET lorsqu’il s’agit d’interagir avec les composants COM. Au lieu d’être limité aux restrictions de .NET Framework Tlbimp.exe (Importateur de bibliothèque de types), telles que la prise en charge limitée des types de données et l’exposition obligatoire de chaque membre de chaque interface COM, C++ Interop permet aux composants COM d’être accessibles à la volonté et ne nécessite pas d’assemblys d’interopérabilité distincts. Contrairement à Visual Basic et C#, Visual C++ peut utiliser des objets COM directement à l’aide des mécanismes COM habituels (tels que CoCreateInstance et QueryInterface). Cela est possible en raison des fonctionnalités d’interopérabilité C++ qui entraînent l’insertion automatique du code de transition entre les fonctions managées et les fonctions non managées, puis de nouveau.
À l’aide de l’interopérabilité C++, les composants COM peuvent être utilisés comme ils sont normalement utilisés ou ils peuvent être encapsulés dans des classes C++. Ces classes wrapper sont appelées wrappers pouvant être appelés wrappers pouvant être appelés runtime personnalisés, ou CRCWs, et ont deux avantages par rapport à l’utilisation de COM directement dans le code d’application :
La classe résultante peut être utilisée à partir de langages autres que Visual C++.
Les détails de l’interface COM peuvent être masqués dans le code client managé. Les types de données .NET peuvent être utilisés à la place de types natifs, et les détails du marshaling de données peuvent être effectués de manière transparente à l’intérieur du CRCW.
Indépendamment de l’utilisation directe ou directe de COM par le biais d’un CRCW, les types d’arguments autres que les types blittables simples doivent être marshalés.
Types blittables
Pour les API non managées qui utilisent des types intrinsèques simples (voir Types Blittable et non Blittable), aucun codage spécial n’est requis, car ces types de données ont la même représentation en mémoire, mais les types de données plus complexes nécessitent un marshaling de données explicite. Pour obtenir un exemple, consultez Guide pratique pour appeler des DLL natives à partir de code managé à l’aide de PInvoke.
Exemple
// vcmcppv2_impl_dllimp.cpp
// compile with: /clr:pure user32.lib
using namespace System::Runtime::InteropServices;
// Implicit DLLImport specifying calling convention
extern "C" int __stdcall MessageBeep(int);
// explicit DLLImport needed here to use P/Invoke marshalling because
// System::String ^ is not the type of the first parameter to printf
[DllImport("msvcrt.dll", EntryPoint = "printf", CallingConvention = CallingConvention::Cdecl, CharSet = CharSet::Ansi)]
// or just
// [DllImport("msvcrt.dll")]
int printf(System::String ^, ...);
int main() {
// (string literals are System::String by default)
printf("Begin beep\n");
MessageBeep(100000);
printf("Done\n");
}
Begin beep
Done
Dans cette section
Guide pratique pour marshaler des chaînes ANSI à l’aide de l’interopérabilité C++
Guide pratique pour marshaler des chaînes Unicode à l’aide de l’interopérabilité C++
Guide pratique pour marshaler des chaînes COM à l’aide de l’interopérabilité C++
Guide pratique pour marshaler des structures à l’aide de l’interopérabilité C++
Guide pratique pour marshaler des tableaux à l’aide de l’interopérabilité C++
Guide pratique pour marshaler des rappels et des délégués à l’aide de l’interopérabilité C++
Guide pratique pour marshaler des pointeurs incorporés à l’aide de l’interopérabilité C++
Guide pratique pour accéder aux caractères d’un System::String
Guide pratique pour convertir la chaîne char * en tableau System::Byte
Guide pratique pour convertir System::String en wchar_t* ou char*
Guide pratique pour convertir System::String en chaîne standard
Guide pratique pour convertir une chaîne standard en System::String
Guide pratique pour obtenir un pointeur vers un tableau d’octets
Guide pratique pour charger des ressources non managées dans un tableau d’octets
Guide pratique pour modifier la classe de référence dans une fonction native
Guide pratique pour déterminer si une image est native ou CLR
Guide pratique pour ajouter une DLL native au Global Assembly Cache
Guide pratique pour stocker une référence à un type valeur dans un type natif
Guide pratique pour stocker la référence d’un objet dans une mémoire non managée
Guide pratique pour procéder à une conversion entre System::Guid et _GUID
Guide pratique pour utiliser un type natif dans une compilation /clr
Guide pratique pour déclarer des handles dans les types natifs
Guide pratique pour inclure une classe native dans un wrapper pour une utilisation par C#
Pour plus d’informations sur l’utilisation de délégués dans un scénario d’interopérabilité, consultez délégué (extensions de composant C++).