共用方式為


外部函式

本文說明在機器碼中呼叫函式的 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& 宣告將傳遞 byrefuint,也就是做為受控指標。 若要取得受控指標,您可以使用 & 運算子的位址。

或者,您可能想要手動管理數據類型的封送處理,並且只使用不受控類型宣告外部函式。

// Using unmanaged types
[<DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)>]
extern int GetBinaryTypeW(nativeint lpApplicationName, uint* lpBinaryType);

您可以使用 Marshal.StringToHGlobalUni 將 .NET 字串轉換成原生格式,並接收可提供給 lpApplicationName 的指標 (nativeint)。

若要取得整數的指標,請使用 && 運算子的指標或 fixed 關鍵詞。

另請參閱