本文說明在機器碼中呼叫函式的 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的功能。 如需詳細資訊,請參閱與非受控程式碼互通。 該區段中的資訊適用於 F# 。
在外部函式中定義參數
當您使用傳回值或參數宣告外部函式時,會使用類似 C 的語法。您可以選擇使用 Managed 宣告(其中 CLR 會在原生和 .NET 類型之間執行一些自動轉換),以及 Unmanaged 宣告,在某些情況下可能會提供更好的效能。 例如,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&
uint宣告將傳遞 的 byref,也就是做為Managed指標。 若要取得 Managed 指標,您可以使用 運算子的 & 位址。
或者,您可能想要手動管理數據類型的封送處理,並且只使用 Unmanaged 類型宣告外部函式。
// Using unmanaged types
[<DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)>]
extern int GetBinaryTypeW(nativeint lpApplicationName, uint* lpBinaryType);
您可以使用Marshal.StringToHGlobalUni 將 .NET 字串轉換成原生格式,並接收可提供給 lpApplicationName的指標 (nativeint)。
若要取得整數的指標,請使用 運算符或 關鍵詞的&&fixed指標。