平台调用 F# 回调函数

Platform Invoke F# callback functions

我在 Raspberry Pi 2(ARM 7,因此是单声道)上使用 F#。我目前正在尝试使用用 C 编写的 WiringPi 库。我已经成功地使用 P/Invoke 来使用一些功能。

现在我正在尝试使用中断(参见 http://wiringpi.com/reference/priority-interrupts-and-threads/),但我被具有以下 C 签名的函数难倒了

int wiringPiISR (int pin, int edgeType,  void (*function)(void));

Daniel Riches 已将其翻译(参见 https://github.com/danriches/WiringPi.Net/blob/master/WiringPi/WrapperClass.cs)成这样的 C# 库

//This is the C# equivelant to "void (*function)(void))" required by wiringPi to define a callback method 
public delegate void ISRCallback(); 

[DllImport("libwiringPi.so", EntryPoint = "wiringPiISR")] 
public static extern int wiringPiISR(int pin, int mode, ISRCallback method); 

我到底要如何在 F# 中执行此操作?我猜 DllImport 行看起来像这样("method" 在 F# 中保留)

[<DllImport("libwiringPi.so", EntryPoint = "wiringPiISR")>] 
  extern int wiringPiISR(int pin, int mode, ISRCallback callBack);

ISRCallback 的类型定义是什么样的?

注意:这不仅仅是 "a" 函数指针,而是一个空指针,带有空参数。

委托定义如下所示:

type ISRCallback = delegate of unit -> unit

平台调用签名如下所示:

[<DllImport("libwiringPi.so", EntryPoint = "wiringPiISR")>] 
extern int wiringPiISR(int pin, int mode, [<MarshalAs(UnmanagedType.FunctionPtr)>]ISRCallback callBack);

函数的用法示例:

let callback : ISRCallback = ISRCallback(fun () -> (*do something interesting here*) ())
let result = wiringPiISR(1, 1, callback)

您应该记住,.NET 中的委托会受到垃圾回收的影响。开发人员有责任确保委托不会 "go out of scope" 直到您的本机库不再需要函数回调。