首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有指针的GetClientRect上的f# p/invoke可以工作,但不能与OutAttribute一起工作

带有指针的GetClientRect上的f# p/invoke可以工作,但不能与OutAttribute一起工作
EN

Stack Overflow用户
提问于 2012-06-22 09:47:09
回答 1查看 914关注 0票数 2

我可以让它工作:

代码语言:javascript
复制
[<DllImport("user32.dll")>]
extern bool GetClientRect(nativeint, RECT*)

let getClientRect hwnd =
    let mutable r = RECT()
    if GetClientRect(hwnd, &&r) = false then
        raise <| System.Exception("GetClientRect failed")
    r

但无论出于什么原因,这只会让r归零,没有抛出异常:

代码语言:javascript
复制
[<DllImport("user32.dll")>]
extern bool GetClientRect(nativeint, [<Out>] RECT rect)

let getClientRect hwnd =
    let mutable r = RECT()
    if GetClientRect(hwnd, r) = false then
        raise <| System.Exception("GetClientRect failed")
    r

当然,使用指针的问题是我得到了警告warning FS0051: The use of native pointers may result in unverifiable .NET IL code,这是可以理解的。

我能错过什么呢?

编辑:尽管已经回答了,但对于记录,结构定义:

代码语言:javascript
复制
[<Struct>]
type RECT =
    val left:int
    val top:int
    val right:int
    val bottom:int
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-06-22 10:40:17

它没有很好的文档记录,但是在F# P/Invoke签名中使用&符号是通过引用传递值的正确(也是最好的)方式。它将编译为与C# ref参数相同的类型签名;将[<Out>]添加到该参数可获得与C# out参数相同的签名。

代码语言:javascript
复制
[<DllImport("user32.dll")>]
extern bool GetClientRect(nativeint hWnd, [<Out>] RECT& rect)

let getClientRect hwnd =
    let mutable r : RECT = Unchecked.defaultOf<_>
    if GetClientRect(hwnd, &r) = false then
        raise <| System.Exception("GetClientRect failed")
    r

请注意,一旦您将P/Invoke签名更改为使用byref<RECT>而不是nativeptr<RECT>,还需要将您在r上使用的address-of运算符(&&)更改为单个“与”(&)。

因为您只能从GetClientRect中获取一个值,所以将可变结果值初始化为Unchecked.defaultOf<_>是一种很好的做法,这样就可以清楚地知道它将被GetClientRect覆盖。

编辑:如果将P/Invoke签名更改为使用byref (&)不起作用,您还可以尝试在返回类型上显式指定编组行为。GetClientRect的MSDN文档说它返回一个BOOL,这与.NET bool不完全相同(BOOL是一个4字节的整数值)。

如果你想尝试一下:

代码语言:javascript
复制
[<DllImport("user32.dll")>]
extern [<return: MarshalAs(UnmanagedType.Bool)>] bool GetClientRect(
    nativeint hWnd, [<Out>] RECT& rect)
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11149250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档