外部函式
本文說明在機器碼中呼叫函式的 F# 語言支援。
語法
[<DllImport( arguments )>]
extern declaration
備註
在先前的語法中,arguments
代表提供給 System.Runtime.InteropServices.DllImportAttribute
屬性的引數。 第一個引數是字串,代表包含此函式的 DLL 名稱 (不含 .dll 副檔名)。 您可以為 System.Runtime.InteropServices.DllImportAttribute
類別的任何公用屬性提供其他引數,例如呼叫慣例。
假設您有原生 C++ DLL,其中包含下列匯出的函式。
#include <stdio.h>
extern "C" void __declspec(dllexport) HelloWorld()
{
printf("Hello world, invoked by F#!\n");
}
您可以使用下列程式碼,從 F# 呼叫此函式。
open System.Runtime.InteropServices
module InteropWithNative =
[<DllImport(@"C:\bin\nativedll", CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()
InteropWithNative.HelloWorld()
與機器碼的互通性稱為「平台叫用」,這是 CLR 的功能。 如需詳細資訊,請參閱與 Unmanaged 程式碼互通。 該節中的資訊適用於 F#。
在外部函式中定義參數
當您使用傳回值或參數宣告外部函式時,會使用類似 C 的語法。您可以選擇使用受控宣告 (其中 CLR 會在原生和 .NET 類型之間執行一些自動轉換),以及不受控宣告,在某些情況下可能會提供更好的效能。 例如,Windows 函式 GetBinaryTypeW 可以兩種不同的方式宣告:
// 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)
指示 CLR 在呼叫函式時,執行 .NET string
與 Windows 原生字串表示之間的自動轉換。 uint&
宣告將傳遞 byref
的 uint
,也就是做為受控指標。 若要取得受控指標,您可以使用 &
運算子的位址。
或者,您可能想要手動管理數據類型的封送處理,並且只使用不受控類型宣告外部函式。
// Using unmanaged types
[<DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)>]
extern int GetBinaryTypeW(nativeint lpApplicationName, uint* lpBinaryType);
您可以使用 Marshal.StringToHGlobalUni 將 .NET 字串轉換成原生格式,並接收可提供給 lpApplicationName
的指標 (nativeint
)。
若要取得整數的指標,請使用 &&
運算子的指標或 fixed
關鍵詞。