为什么以下代码不起作用?

open System
open System.Runtime.InteropServices
open System.ComponentModel

[<DllImport("kernel32")>]
extern int AddDllDirectory(string NewDirectory)

[<EntryPoint>]
let main argv =
    let result = AddDllDirectory("c:\\")
    if result = 0 then
        printfn "%A" <| Win32Exception(Marshal.GetLastWin32Error())
        // Prints: "System.ComponentModel.Win32Exception (0x80004005): The parameter is incorrect"
    System.Console.ReadLine() |> ignore
    0 // return an integer exit code

最佳答案

AddDllDirectory()是winapi的最新添加。它只能保证在Windows 8中可用,要在早期Windows版本上获取它,需要更新KB2533623。选择产品要求时请牢记这一点。

这在不只一种方式上是不寻常的,它没有遵循Winapi函数接受字符串的正常模式。这使该函数有两个版本可用,ANSI版本附加A和Unicode版本附加W。 AddDllDirectory()没有附加字母,仅存在Unicode版本。我不清楚这是故意的还是疏忽大意的。 Windows 8 SDK标头中缺少函数声明,这确实非常不寻常。

因此,您的原始声明失败,因为您调用了Unicode版本,但pinvoke编组传递了ANSI字符串。您可能很幸运,因为该字符串包含奇数个字符,且具有足够的幸运零而不引起AccessViolation。

需要在[DllImport]声明中使用CharSet属性,以便pinvoke编组传递一个Unicode字符串。

09-11 23:48