为什么以下代码不起作用?
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
Run Code Online (Sandbox Code Playgroud)
Han*_*ant 17
AddDllDirectory()是winapi的最新成员.它仅保证在Windows 8中可用,在早期Windows版本上获取它需要更新KB2533623.在选择产品要求时,请注意这一点.
它不止一种方式,它不遵循接受字符串的winapi函数的正常模式.这使得该函数有两个版本,附加A的ANSI版本和附加W的Unicode版本.AddDllDirectory()没有附加字母,只存在Unicode版本.我不清楚这是故意还是疏忽,故意的可能性很高.Windows 8 SDK标头中缺少函数声明,确实非常不寻常.
因此,您的原始声明失败,因为您调用了Unicode版本,但是pinvoke marshaller传递了一个ANSI字符串.你可能很幸运,因为字符串有奇数个字符,有足够的幸运零,不会导致AccessViolation.
需要在[DllImport]声明中使用CharSet属性,以便pinvoke marshaller传递Unicode字符串.
您需要指定在DllImport属性中使用unicode,
[<DllImport("kernel32", CharSet=CharSet.Unicode)>]
extern int AddDllDirectory(string NewDirectory)
Run Code Online (Sandbox Code Playgroud)