Fungsi Eksternal
Artikel ini menjelaskan dukungan bahasa F# untuk memanggil fungsi dalam kode asli.
Sintaks
[<DllImport( arguments )>]
extern declaration
Keterangan
Dalam sintaks sebelumnya, arguments
mewakili argumen yang disediakan ke System.Runtime.InteropServices.DllImportAttribute
atribut . Argumen pertama adalah string{i> System.Runtime.InteropServices.DllImportAttribute, seperti konvensi panggilan.
Asumsikan Anda memiliki C++ DLL asli yang berisi fungsi yang diekspor berikut.
#include <stdio.h>
extern "C" void __declspec(dllexport) HelloWorld()
{
printf("Hello world, invoked by F#!\n");
}
Anda dapat memanggil fungsi ini dari F# dengan menggunakan kode berikut.
open System.Runtime.InteropServices
module InteropWithNative =
[<DllImport(@"C:\bin\nativedll", CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()
InteropWithNative.HelloWorld()
Interoperabilitas dengan kode asli disebut sebagai pemanggilan platform dan merupakan fitur dari CLR. Untuk informasi selengkapnya, lihat Mengoperasikan dengan Kode Tidak Terkelola. Informasi di bagian tersebut berlaku untuk F#.
Menentukan Parameter dalam Fungsi Eksternal
Saat Anda mendeklarasikan fungsi eksternal dengan nilai atau parameter yang dikembalikan, Anda menggunakan sintaks yang mirip dengan C. Anda memiliki opsi untuk menggunakan deklarasi terkelola (di mana CLR akan melakukan beberapa konversi otomatis antara jenis asli dan .NET) dan deklarasi yang tidak dikelola, yang mungkin menawarkan performa yang lebih baik dalam beberapa keadaan. Misalnya, fungsi Windows GetBinaryTypeW dapat dideklarasikan dengan dua cara berbeda:
// 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)
menginstruksikan CLR untuk melakukan konversi otomatis antara representasi string asli .NET string
dan Windows saat fungsi dipanggil. uint&
menyatakan uint
bahwa akan diteruskan byref
, yaitu, sebagai penunjuk terkelola. Untuk mendapatkan pointer terkelola, Anda menggunakan alamat &
operator.
Secara bergantian, Anda mungkin ingin mengelola marsekal jenis data secara manual dan mendeklarasikan fungsi eksternal hanya menggunakan jenis yang tidak dikelola.
// Using unmanaged types
[<DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)>]
extern int GetBinaryTypeW(nativeint lpApplicationName, uint* lpBinaryType);
Anda dapat menggunakanMarshal.StringToHGlobalUni untuk mengonversi string .NET ke format asli dan menerima pointer (nativeint
) ke dalamnya yang dapat disediakan ke lpApplicationName
.
Untuk mendapatkan pointer ke bilangan &&
bulat, gunakan penunjuk operator atau fixed
kata kunci.