Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo descrive il supporto del linguaggio F# per chiamare le funzioni nel codice nativo.
Sintassi
[<DllImport( arguments )>]
extern declaration
Osservazioni:
Nella sintassi precedente, arguments rappresenta gli argomenti forniti all'attributo System.Runtime.InteropServices.DllImportAttribute . Il primo argomento è una stringa che rappresenta il nome della DLL che contiene questa funzione, senza l'estensione .dll. È possibile specificare argomenti aggiuntivi per qualsiasi proprietà pubblica della System.Runtime.InteropServices.DllImportAttribute classe, ad esempio la convenzione di chiamata.
Si supponga di avere una DLL C++ nativa che contiene la funzione esportata seguente.
#include <stdio.h>
extern "C" void __declspec(dllexport) HelloWorld()
{
printf("Hello world, invoked by F#!\n");
}
È possibile chiamare questa funzione da F# usando il codice seguente.
open System.Runtime.InteropServices
module InteropWithNative =
[<DllImport(@"C:\bin\nativedll", CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()
InteropWithNative.HelloWorld()
L'interoperabilità con il codice nativo viene definita platform invoke ed è una funzionalità di CLR. Per altre informazioni, vedere Interoperabilità con codice non gestito. Le informazioni contenute in questa sezione sono applicabili a F#.
Definizione di parametri in funzioni esterne
Quando si dichiarano funzioni esterne con valori o parametri restituiti, si usa una sintassi simile a C. È possibile usare le dichiarazioni gestite (in cui CLR eseguirà alcune conversioni automatiche tra tipi nativi e .NET) e dichiarazioni non gestite, che potrebbero offrire prestazioni migliori in alcune circostanze. Ad esempio, la funzione Windows GetBinaryTypeW può essere dichiarata in due modi diversi:
// 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) indica a CLR di eseguire una conversione automatica tra una rappresentazione di stringa nativa .NET string e Windows quando viene chiamata la funzione.
uint& dichiara un oggetto uint che verrà passato byref, ovvero, come puntatore gestito. Per ottenere un puntatore gestito, usare l'indirizzo dell'operatore & .
In alternativa, è possibile gestire manualmente il marshalling dei tipi di dati e dichiarare le funzioni esterne usando solo tipi non gestiti.
// Using unmanaged types
[<DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)>]
extern int GetBinaryTypeW(nativeint lpApplicationName, uint* lpBinaryType);
È possibile usareMarshal.StringToHGlobalUni per convertire una stringa .NET in formato nativo e ricevere un puntatore (nativeint) in tale stringa che potrebbe essere fornito a lpApplicationName.
Per ottenere un puntatore a un numero intero, usare il puntatore dell'operatore && o la fixed parola chiave .