2017-03-23 3 views
3
open System 
open System.Diagnostics 
open System.Runtime.InteropServices 
module PInvoke = 
    type EnumThreadDelegate= delegate of (IntPtr * IntPtr) -> bool 
    type ComArrayList() = 
     inherit System.Collections.ArrayList() 

    [<DllImport("user32.dll")>] 
    extern [<return: MarshalAs(UnmanagedType.Bool)>] bool private EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam); 
    let getThreadWindows (threadId:int) : _ list = 
     let items = ResizeArray() 
     let withData (hWnd:IntPtr, lParam:IntPtr) = 
      let _ = items.Add(hWnd,lParam) 
      true 
     let f = EnumThreadDelegate withData 

     EnumThreadWindows (threadId, f, IntPtr.Zero) |> ignore<bool> 
     items 
     |> Seq.cast<IntPtr*IntPtr> 
     |> List.ofSeq 


let lp = Process.GetProcesses() |> Seq.filter(fun p -> p.ProcessName.StartsWith("L")) |> Seq.minBy(fun p -> p.StartTime) 
lp.Threads 
|> Seq.cast<ProcessThread> 
|> Seq.map (fun t -> t.Id) 
|> Seq.map PInvoke.getThreadWindows 
|> List.ofSeq 

System.Runtime.InteropServices.MarshalDirectiveException: Cannot marshal 'parameter #1': Generic types cannot be marshaledなぜこれらの両方がコンパイルされますが、どちらか一方だけが実行されますか?

を与えるが、これは、コンパイルし、実行:

open System 
open System.Diagnostics 
open System.Runtime.InteropServices 
module PInvoke = 
    type EnumThreadDelegate= delegate of IntPtr * IntPtr -> bool 
    type ComArrayList() = 
     inherit System.Collections.ArrayList() 

    [<DllImport("user32.dll")>] 
    extern [<return: MarshalAs(UnmanagedType.Bool)>] bool private EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam); 
    let getThreadWindows (threadId:int) : _ list = 
     let items = ResizeArray() 
     let withData (hWnd:IntPtr) (lParam:IntPtr) = 
      let _ = items.Add(hWnd,lParam) 
      true 
     let f = EnumThreadDelegate withData 

     EnumThreadWindows (threadId, f, IntPtr.Zero) |> ignore<bool> 
     items 
     |> Seq.cast<IntPtr*IntPtr> 
     |> List.ofSeq 


let lp = Process.GetProcesses() |> Seq.filter(fun p -> p.ProcessName.StartsWith("L")) |> Seq.minBy(fun p -> p.StartTime) 
lp.Threads 
|> Seq.cast<ProcessThread> 
|> Seq.map (fun t -> t.Id) 
|> Seq.map PInvoke.getThreadWindows 
|> List.ofSeq 

はなぜコンパイルん両方が、一つは、例外を与えますか?

delegate of (IntPtr*IntPtr) -> booldelegate of IntPtr*IntPtr->boolの違いは何ですか? 同じものであってはなりませんか? はIntPtr*IntPtrと同じではありませんか?

答えて

4

私は

delegate of IntPtr*IntPtr -> bool 

は、その2つの引数として2 IntPtr秒かかり、二引数のデリゲートであるのに対し、

delegate of (IntPtr*IntPtr) -> bool 

は、Tuple<IntPtr,IntPtr>を取る一引数デリゲートだと思います。

関連する問題