Funzioni esterne

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 .

Vedi anche