Utilisation de l'interopérabilité C++ (PInvoke implicite)
Mise à jour : novembre 2007
Contrairement à d'autres langages .NET, Visual C++ offre une prise en charge de l'interopérabilité qui autorise la présence de code managé et non managé dans la même application et également dans le même fichier (avec les pragmas managed, unmanaged). Cela permet aux développeurs Visual C++ d'intégrer des fonctionnalités .NET dans des applications Visual C++ existantes sans perturber le reste de l'application.
Vous pouvez également appeler des fonctions non managées à partir d'un module (compiland) managé à l'aide de dllexport, dllimport.
Un PInvoke implicite peut être utile si vous n'avez pas besoin de spécifier de quelle manière les paramètres de fonction doivent être marshalés, ou l'un des autres détails pouvant être spécifiés lors d'un appel explicite à DllImportAttribute.
Visual C++ offre aux fonctions managées et non managées deux moyens d'interagir :
Un PInvoke explicite est pris en charge par le .NET Framework et est disponible dans la plupart des langages .NET. Cependant, comme son nom l'indique, C++ Interop est spécifique à Visual C++.
C++ Interop
C++ Interop est recommandé par rapport au PInvoke explicite, car il assure une meilleure sécurité de type, est généralement moins fastidieux à implémenter, est plus indulgent en cas de modification de l'API non managée et autorise des améliorations des performances qui n'étaient pas possibles avec un PInvoke explicite. Toutefois, C++ Interop ne peut pas être utilisé si le code source non managé n'est pas disponible ou en cas de compilation avec /clr:safe (consultez Code pur et vérifiable pour plus d'informations).
C++ COM Interop
Les fonctionnalités d'interopérabilité prises en charge par Visual C++ procurent un avantage particulier par rapport aux autres langages .NET en termes d'interaction avec des composants COM. Plutôt que d'être limité aux restrictions du .NET Framework Type Library Importer (Tlbimp.exe), 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 autorise l'accès à volonté aux composants COM et n'exige pas d'assemblys d'interopérabilité distincts. Pour plus d'informations, consultez Utilisation de serveurs COM natifs à partir du .NET.
Types blittables
Pour les API non managées qui utilisent des types intrinsèques simples (consultez Types blittables et non blittables), aucun codage spécial n'est requis, car ces types de données possèdent la même représentation en mémoire, mais les types de données plus complexes requièrent le marshaling explicite de données. Pour obtenir un exemple, consultez Comment : appeler des DLL natives à partir du 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
Comment : marshaler des chaînes ANSI à l'aide de l'interopérabilité C++
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++
Comment : marshaler des structures à l'aide de l'interopérabilité C++
Comment : marshaler des tableaux à l'aide de l'interopérabilité C++
Comment : marshaler des rappels et des délégués à l'aide de l'interopérabilité C++
Comment : marshaler des pointeurs incorporés à l'aide de l'interopérabilité C++
Comment : convertir la chaîne char * en tableau System::Byte
Comment : charger des ressources non managées dans un tableau d'octets
Comment : modifier la classe de référence dans une fonction native
Comment : stocker une référence à un type valeur dans un type natif
Comment : stocker la référence d'un objet dans une fonction native
Comment : procéder à une conversion entre System::Guid et _GUID
Comment : encapsuler une classe native 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 delegate.