2012-03-13 8 views
1

プラットフォームの呼び出しを使用して、いくつかのマルチモニターの処理をしようとしています。私はhttp://pinvoke.netを使い始めましたが、定義が一致しない問題が発生しました。 MONITORINFO (user32)(及びMONITORINFOEX (user32))においてcbSizeがMonitorInfoのintまたはuintである必要があるかどうかを確認するにはどうすればよいですか?

、サイズが次のように定義される。

public int Size; 

しかしEnumDisplayMonitors (user32)でのMonitorInfoを使用するサンプルコードでは、我々は以下を参照してください明らか

mi.size = (uint)Marshal.SizeOf(mi); 

、これらのいずれかを正しいものではありません。バイトで、

構造のサイズとして定義

typedef struct tagMONITORINFO { 
    DWORD cbSize; 
    RECT rcMonitor; 
    RECT rcWork; 
    DWORD dwFlags; 
} MONITORINFO, *LPMONITORINFO; 

cbSizeのを有する:としてMSDNのドキュメントで

は、MONITORINFOが宣言されます。

GetMonitorInfo関数を呼び出す前に、このメンバーをsizeof(MONITORINFO)に設定してください。そうすることで、関数が渡す構造体の型を決定することができます。

どのように私はそれがint、またはuintであるべきであるかを考えることができますか?

注:私はこのようなもののいくつかはのSystem.Windows.Formsで利用可能です知っているが、私はシルバー5に

答えて

1

DWORDを使用してこのP /呼び出しをやろうとしている符号なし32ビット整数であるので、uint技術的に正しいです。

intを使用するバージョンは、おそらく軽度の倦怠感によって行われました。作者はおそらくMarshal.SizeOf()の戻り値をuintにキャストしたくないと思っていました。

実際には、cbSizeは、符号付きから符号なしへの変換によって差異が生じる点に決して到達しないため、ここでは重要ではありません。ただし、場合によっては問題となることがあります。たとえば、ビットフラグの組み合わせを保持する変数。

1

ネイティブタイプは、Windows APIのunsigned intの別名であるDWORDです。どちらが理にかなっていますが、構造体のサイズは決して負ではありません。しかし、そのような構造体のピンボケ宣言は、uintの代わりにintを使用することがよくあります。これはpinvoke.netによって提供されるdeclarationで行います。

これは便宜上、Marshal.SizeOf()は、uintではなくintを返します。これは、CLSCompliantというメソッドを作るために行われました。無署名型をサポートしない多くの言語があります。 Javaと元のVisual Basicは良い例です。

これはではありません。問題です。intとuintは、0からint.MaxValueまでの値で同じサイズと同じビットパターンを持ちます。 uintが重要であるようにint.MaxValueを超えて行くことは実用的な問題ではありません。構造体はそれほど大きくはありません。とにかくそれがあったとしても、それはとにかく使えなくなるでしょう.CLRは2GBを超える管理型をサポートしていません。少なくとも.NET 4.5まで。

質問に答えるために、コードスニペットは構造メンバをuintとして宣言した誰かによって書き込まれたため、キャストが必要です。どちらの方法でも問題ありません。

関連する問題