从P/Invoke修改结构布局



我正在寻找最佳练习指导,围绕更改返回/传递给P/Invoke功能的对象的结构/类布局。我已经搜索了这个答案,但也许我太累了,我没有有效地搜索。

我可以提出的最简单的示例(真正的一个太复杂了),是诸如getWindowRect。

如果我想在rect struct中添加一些额外的属性,我应该将其添加到结构本身的定义中,还是应该切换到子类以添加额外的属性?

Microsoft或其他可靠来源围绕以下方法有最佳实践吗?这两个都反对最佳实践吗?

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(HandleRef hWnd, out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int Left;        // x position of upper-left corner
    public int Top;         // y position of upper-left corner
    public int Right;       // x position of lower-right corner
    public int Bottom;      // y position of lower-right corner
    public string Extra;    // ADDED
}

vors

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(HandleRef hWnd, out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
public class RECT
{
    public int Left;        // x position of upper-left corner
    public int Top;         // y position of upper-left corner
    public int Right;       // x position of lower-right corner
    public int Bottom;      // y position of lower-right corner
}
public class RectEx : RECT
{
    public string Extra;    // Added
    public RectEx(RECT r)
    {
        Left = r.Left;
        Top = r.Top;
        Right = r.Right;
        Bottom = r.Bottom;
        Extra = "test";
    }
}

这是另一个选项:这允许您维护本地功能并在使用的对象上提供一些安全性。

// used internally in native method
[StructLayout(LayoutKind.Sequential)]
internal struct RECT
{
    public int Left;        // x position of upper-left corner
    public int Top;         // y position of upper-left corner
    public int Right;       // x position of lower-right corner
    public int Bottom;      // y position of lower-right corner
}

// public accessible struct with extra fields 
public struct RectEx
{
    public int Left;        // x position of upper-left corner
    public int Top;         // y position of upper-left corner
    public int Right;       // x position of lower-right corner
    public int Bottom;      // y position of lower-right corner
    public dynamic Extra = "Extra";
}

public static class UnsafeNativeMethods
{
    //used internally to populate RECT struct
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetWindowRect(HandleRef hWnd, out RECT lpRect);
    //public safe method with exception handling and returns a RectEx
    public static RectEx GetWindowRectangle(HandleRef hWnd)
    {
        RECT r = new RECT();
        RectEx result = new RectEx();
        try
        {
            GetWindowRect(hWnd, r);
            result.Left = r.Left;
            result.Top = r.Top;
            result.Right = r.Right;
            result.Bottom = r.Bottom;
            // assign extra fields
        }
        catch(Exception ex)
        {
            // handle ex
        }
    return result;
    }
}

您也可以使用: structlayout(layoutkind.explitic)

[StructLayout(LayoutKind.Sequential)]
public struct Point 
{
   public int x;
   public int y;
}   
[StructLayout(LayoutKind.Explicit)]
public struct Rect 
{
   [FieldOffset(0)] public int left;
   [FieldOffset(4)] public int top;
   [FieldOffset(8)] public int right;
   [FieldOffset(12)] public int bottom;
}   

(来自http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.layoutkind.aspx)

相关内容

  • 没有找到相关文章

最新更新