标准库中某处是否定义了unit-> unit的委托?

时间:2018-08-09 08:41:25

标签: f#

为了异步错误处理,我需要向Cuda流添加回调。我有一个看起来像这样的函数,需要在Spiral中进行重写,并将其编译为F#。

type unit_to_unit_delegate = delegate of unit -> unit
let add_callback_to_stream (str : CudaStream) (callback : unit -> unit) =
    let callb (str : CUstream) (res : CUResult) (p : nativeint) =
        let t : unit_to_unit_delegate = Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(p)
        t.Invoke()

    let aux = new unit_to_unit_delegate (callback)
    let ptr_to_aux = Marshal.GetFunctionPointerForDelegate aux

    let cuda_callback = CUstreamCallback(callb)
    str.AddCallback(cuda_callback,ptr_to_aux,CUStreamAddCallbackFlags.None)

第一行是给我麻烦的那一行。我没有办法像在F#中那样在Spiral中明确声明委托类型。我通常使用宏进行互操作,但是在这里我无法使用它们。

如果未在某个地方的库中定义它,我可能需要修改代码生成器,以在编译开始时打印出type unit_to_unit_delegate = delegate of unit -> unit

1 个答案:

答案 0 :(得分:2)

有一系列通用的.NET委托System.ActionSystem.Func可以满足您的需求。这些由.NET定义,因此它们使用void而不是unit。根据您的用例,可能会很好,但是如果您做的比较棘手,则可能会遇到问题。给定类型为callback的F#函数unit -> unit,您可以使用:

  • System.Action是一个没有参数返回void的委托。 F#可以使用callback

  • 自动将new System.Action(callback)转换为此委托人
  • System.Action<T>是一个委托,它接受一个类型为T的参数并返回void。 F#也可以将callback转换为这种类型:new System.Action<unit>(callback)

  • System.Func<T, R>是一个接受T并返回R的委托。同样,您可以使用
    new System.Func<unit, unit>(callback)获得一个Func<unit, unit>

我将从第一个开始,除非您明确需要将委托编译为.NET代码并返回Microsoft.FSharp.Core.Unit的委托。

相关问题