外部関数
この記事では、ネイティブ コードでの関数の呼び出しに関する 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 のような構文を使います。マネージド宣言 (CLR によって、ネイティブ型と .NET 型の間のいくつかの自動変換が実行されます) と、状況によってはパフォーマンスが向上する可能性があるアンマネージド宣言を使用するオプションがあります。 たとえば、Windows 関数 GetBinaryTypeW は、次の 2 つの方法で宣言できます。
// 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)
は、関数が呼び出されるときに、.NET の string
と Windows のネイティブ文字列表現の間で自動変換を実行するよう、CLR に指示します。 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
キーワードを使います。
関連項目
.NET