2

ap/invoke 関数に返される/渡されるオブジェクトの構造体/クラス レイアウトの変更に関するベスト プラクティス ガイダンスを探しています。これに対する答えを探しましたが、疲れすぎて効果的に検索していないのかもしれません。

私が思いつく最も単純な例 (実際の例はここでは少し複雑すぎます) は、GetWindowRectのようなものです。

RECT 構造体にいくつかの追加プロパティを追加したい場合、構造体自体の定義に追加するだけですか、それともサブクラス化に切り替えて追加プロパティを追加する必要がありますか?

次の方法に関して、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
}

[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";
    }
}
4

2 に答える 2

1

別のオプションがあります。これにより、ネイティブ機能を維持でき、使用しているオブジェクトに対してある程度の安全性が提供されます。

// 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;
    }
}
于 2012-11-08T09:55:41.023 に答える