Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de changer d’annuaire.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer d’annuaire.
Cet article décrit la prise en charge du langage F# pour appeler des fonctions dans du code natif.
Syntaxe
[<DllImport( arguments )>]
extern declaration
Remarques
Dans la syntaxe précédente, arguments représente les arguments fournis à l’attribut System.Runtime.InteropServices.DllImportAttribute . Le premier argument est une chaîne qui représente le nom de la DLL qui contient cette fonction, sans l’extension .dll. Des arguments supplémentaires peuvent être fournis pour toutes les propriétés publiques de la System.Runtime.InteropServices.DllImportAttribute classe, telles que la convention d’appel.
Supposons que vous disposez d’une DLL C++ native qui contient la fonction exportée suivante.
#include <stdio.h>
extern "C" void __declspec(dllexport) HelloWorld()
{
printf("Hello world, invoked by F#!\n");
}
Vous pouvez appeler cette fonction à partir de F# à l’aide du code suivant.
open System.Runtime.InteropServices
module InteropWithNative =
[<DllImport(@"C:\bin\nativedll", CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()
InteropWithNative.HelloWorld()
L’interopérabilité avec du code natif est appelée appel de plateforme et est une fonctionnalité du CLR. Pour plus d'informations, consultez Interopérabilité avec le code non géré. Les informations de cette section s’appliquent à F#.
Définition de paramètres dans les fonctions externes
Lorsque vous déclarez des fonctions externes avec des valeurs ou des paramètres de retour, vous utilisez une syntaxe similaire à C. Vous avez la possibilité d’utiliser les déclarations managées (où le CLR effectue certaines conversions automatiques entre les types natifs et .NET) et les déclarations non managées, ce qui peut offrir de meilleures performances dans certaines circonstances. Par exemple, la fonction Windows GetBinaryTypeW peut être déclarée de deux façons différentes :
// Using automatic marshaling of managed types
[<DllImport("kernel32.dll",
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Unicode,
ExactSpelling = true)>]
extern bool GetBinaryTypeW([<MarshalAs(UnmanagedType.LPWStr)>] string lpApplicationName, uint& lpBinaryType);
MarshalAs(UnmanagedType.LPWStr) indique au CLR d’effectuer une conversion automatique entre une représentation sous forme de chaîne native .NET string et Windows lorsque la fonction est appelée.
uint& déclare un uint pointeur managé qui sera passé byref, autrement dit, en tant que pointeur managé. Pour obtenir un pointeur managé, vous utilisez l’adresse de l’opérateur & .
Vous pouvez également gérer manuellement le marshaling des types de données et déclarer les fonctions externes en utilisant uniquement des types non managés.
// Using unmanaged types
[<DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)>]
extern int GetBinaryTypeW(nativeint lpApplicationName, uint* lpBinaryType);
Vous pouvez utiliserMarshal.StringToHGlobalUni pour convertir une chaîne .NET en format natif et recevoir un pointeur (nativeint) vers celui-ci qui peut être fourni à lpApplicationName.
Pour obtenir un pointeur vers un entier, utilisez le pointeur d’opérateur && ou le fixed mot clé.