f# - 平台调用 F# 回调函数

标签 f# mono pinvoke raspberry-pi2

我在 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 行看起来像这样(“方法”在 F# 中保留)

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

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

注意:这不仅仅是“一个”函数指针,而且是一个带有 void 参数的 void 函数指针。

最佳答案

委托(delegate)定义如下所示:

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 中的委托(delegate)会受到垃圾回收的影响。开发人员有责任确保委托(delegate)不会“超出范围”,直到您的 native 库不再需要函数回调为止。

关于f# - 平台调用 F# 回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34030005/

相关文章:

F# ionide websharperserverclient - 如何运行

mono - Mono 上的 ServiceStack 示例

c# - 从一个线程多次调用 NetworkStream.BeginWrite 是否安全?

c# - Win32 API P-Invoke 使磁盘联机、脱机并设置唯一 ID

c# - F# 指针成员访问器

f# - 如何使这段代码更加紧凑和惯用?

f# - 使用 F# Struct 和 Explicit LayoutKind 创建标记联合

f# - F# 显式类型参数的用例是什么?

linux - 使用 Apache2 的 Linux 上的 WCF 服务

c# - C# 中的指针数学