我在 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/