Externe Funktionen
Dieser Artikel beschreibt die Unterstützung der Sprache F# für den Aufruf von Funktionen in nativem Code.
Syntax
[<DllImport( arguments )>]
extern declaration
Hinweise
In der vorherigen Syntax steht arguments
für Argumente, die dem Attribut System.Runtime.InteropServices.DllImportAttribute
übergeben werden. Das erste Argument ist eine Zeichenfolge, die den Namen der DLL (ohne die Erweiterung „.dll“) repräsentiert, die diese Funktion enthält. Für jede der öffentlichen Eigenschaften der Klasse System.Runtime.InteropServices.DllImportAttribute
können zusätzliche Argumente angegeben werden, z. B. die Aufrufkonvention.
Angenommen, Sie verfügen über eine native C++-DLL, die die folgende exportierte Funktion enthält.
#include <stdio.h>
extern "C" void __declspec(dllexport) HelloWorld()
{
printf("Hello world, invoked by F#!\n");
}
Sie können diese Funktion aus F# mit dem folgenden Code aufrufen.
open System.Runtime.InteropServices
module InteropWithNative =
[<DllImport(@"C:\bin\nativedll", CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()
InteropWithNative.HelloWorld()
Die Interoperabilität mit nativem Code wird als Plattformaufruf bezeichnet und ist ein Feature der CLR. Weitere Informationen finden Sie unter Interoperation mit nicht verwaltetem Code. Die Informationen in diesem Abschnitt gelten für F#.
Definieren von Parametern in externen Funktionen
Bei der Deklaration externer Funktionen mit Rückgabewerten oder Parametern verwenden Sie eine ähnliche Syntax wie in C. Sie haben die Möglichkeit, verwaltete Deklarationen (bei denen die CLR einige automatische Konvertierungen zwischen nativen und .NET-Typen durchführt) und nicht verwaltete Deklarationen zu verwenden, die unter Umständen eine bessere Leistung bieten. Beispielsweise kann die Windows-Funktion GetBinaryTypeW auf zwei verschiedene Arten deklariert werden:
// 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)
weist die CLR an, eine automatische Konvertierung zwischen einer .NET-Zeichenfolge (string
) und einer Windows-nativen Zeichenfolgendarstellung durchzuführen, wenn die Funktion aufgerufen wird. uint&
deklariert ein uint
, das als verwalteter Zeiger (d.h. byref
) übergeben wird. Um einen verwalteten Zeiger zu erhalten, verwenden Sie die Adresse des &
-Operators.
Alternativ könnten Sie das Marshalling von Datentypen manuell verwalten und die externen Funktionen nur mit nicht verwalteten Typen deklarieren.
// Using unmanaged types
[<DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)>]
extern int GetBinaryTypeW(nativeint lpApplicationName, uint* lpBinaryType);
Sie können Marshal.StringToHGlobalUni verwenden, um eine .NET-Zeichenfolge in ein natives Format zu konvertieren und einen Zeiger (nativeint
) darauf zu erhalten, der für lpApplicationName
bereitgestellt werden kann.
Um einen Zeiger für einen Integer-Wert zu erhalten, verwenden Sie den Zeiger des &&
-Operators oder das Schlüsselwort fixed
.