Externí funkce
Tento článek popisuje podporu jazyka F# pro volání funkcí v nativním kódu.
Syntaxe
[<DllImport( arguments )>]
extern declaration
Poznámky
V předchozí syntaxi arguments
představuje argumenty zadané atributu System.Runtime.InteropServices.DllImportAttribute
. Prvním argumentem je řetězec, který představuje název knihovny DLL, která obsahuje tuto funkci bez rozšíření .dll. Další argumenty lze zadat pro kteroukoli z veřejných vlastností System.Runtime.InteropServices.DllImportAttribute
třídy, jako je volání konvence.
Předpokládejme, že máte nativní knihovnu DLL jazyka C++, která obsahuje následující exportovanou funkci.
#include <stdio.h>
extern "C" void __declspec(dllexport) HelloWorld()
{
printf("Hello world, invoked by F#!\n");
}
Tuto funkci můžete volat z jazyka F# pomocí následujícího kódu.
open System.Runtime.InteropServices
module InteropWithNative =
[<DllImport(@"C:\bin\nativedll", CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()
InteropWithNative.HelloWorld()
Interoperabilita s nativním kódem se označuje jako volání platformy a je funkcí CLR. Další informace najdete v tématu Spolupráce s nespravovaným kódem. Informace v této části platí pro jazyk F#.
Definování parametrů v externích funkcích
Když deklarujete externí funkce s návratovými hodnotami nebo parametry, použijete syntaxi podobnou jazyku C. Máte možnost použít spravované deklarace (kde CLR provede některé automatické převody mezi nativními a nespravovanými deklaracemi) a nespravovanými deklaracemi, které můžou v některých případech nabízet lepší výkon. Například funkci Windows GetBinaryTypeW lze deklarovat dvěma různými způsoby:
// 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)
dává clr pokyn, aby při zavolání funkce provedl automatický převod mezi nativní řetězcovou reprezentací .NET string
a Windows. uint&
deklaruje uint
, že bude předán byref
, to znamená, jako spravovaný ukazatel. Chcete-li získat spravovaný ukazatel, použijte adresu operátoru &
.
Případně můžete chtít spravovat zařazování datových typů ručně a deklarovat externí funkce pouze pomocí nespravovaných typů.
// Using unmanaged types
[<DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)>]
extern int GetBinaryTypeW(nativeint lpApplicationName, uint* lpBinaryType);
Můžete použítMarshal.StringToHGlobalUni k převodu řetězce .NET do nativního formátu a přijetí ukazatele (nativeint
) na něj, který lze zadat do lpApplicationName
.
Chcete-li získat ukazatel na celé číslo, použijte ukazatel operátoru &&
fixed
nebo klíčové slovo.