2009-11-06 4 views
7

Je ne suis pas sûr de la syntaxe pour cela. J'essaie de traduire ce code C# en F #.Syntaxe F # pour la signature P/Invoke en utilisant MarshalAs

struct LASTINPUTINFO 
{ 
    public uint cbSize; 
    public uint dwTime; 
} 

public class IdleTimer 
{ 
    [DllImport("User32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); 
} 

C'est ce que j'ai jusqu'à présent.

type LASTINPUTINFO = { 
    cbSize : UInt32; 
    dwTime : UInt32; 
} 

type IdleTimer = 
    [<DllImport("User32.dll")>] 
    [<return: MarshalAs(UnmanagedType.Bool)>] 
    extern GetLastInputInfo(plii : LASTINPUTINFO ref) 

Répondre

8

Honnêtement, je n'ai pas essayé de courir ou de l'utiliser, mais cette compile, et nous espérons vous orienter dans la bonne direction.

open System 
open System.Runtime.InteropServices 

[<Struct>] 
type LASTINPUTINFO = 
    val cbSize : UInt32 
    val dwTime : UInt32 

module IdleTimer = 
    [<DllImport("User32.dll")>] 
    extern [<MarshalAs(UnmanagedType.Bool)>] bool GetLastInputInfo([<In>][<Out>] LASTINPUTINFO plii) 
10

Outre le commentaire de Brian, il peut être intéressant de souligner que F signatures # EXTERN reflètent les signatures C assez fidèlement, de sorte que plutôt que d'utiliser les [<In>][<Out>] attributs sur la référence, vous pouvez déclarer probablement le paramètre comme LASTINPUTINFO* plii, puis passez une référence à une instance locale à l'aide de l'opérateur & & lors de l'appel de la fonction.

3

En plus du commentaire de kvb, j'ai trouvé que déclarer des paramètres en tant que pointeurs endommage le moteur de refactorisation de FSharp Power Tools actuel. Vous pouvez utiliser un IntPtr pour contourner cela:

open System 
open System.Runtime.InteropServices 
open Microsoft.FSharp.NativeInterop 

[<Struct>] 
type LASTINPUTINFO = 
    val mutable cbSize : uint32 
    val dwTime : uint32 

[<DllImport("user32.dll")>] 
extern bool GetLastInputInfo(IntPtr p) 

let getLastInputTime() = 
    let mutable time = LASTINPUTINFO(cbSize = 8u) 
    GetLastInputInfo(NativePtr.toNativeInt &&time) |> ignore 
    time.dwTime