私は基本的に異なるMarshal.SizeOf()
とsizeof()
の違いがわかっています。しかし、IntPtr
の場合、両方とも常にはCPUアーキテクチャに関係なくまったく同じものを返しますか?Marshal.SizeOf(typeof(IntPtr))とsizeof(IntPtr)
答えて
まず、知りたいのはなぜですか?あなたのコードがよく書かれている場合は、sizeof
とMarshal.SizeOf
が返すものについて何も仮定する必要はありません。あなたのIntPtr
インスタンスのいずれかをマーシャリングするためにマーシャラーを使用しますか?次に、Marshal.SizeOf
を使用します。あなたの変数は管理された世界を離れることはありませんか、カスタムマーシャリングを使用していますか?その後、sizeof
(またはunsafe
ブロックを必要としないので、IntPtr.Size
)を使用します。いずれの場合でも、これらの値が同じ値を返すかどうかは関係ありません。それが実用的な答えです。
オン理論。 C# language specificationによれば、sizeof(IntPtr)
に返される値は、 "IntPtr
が構造体であるため、"すべてのパディングを含むその型の変数の合計バイト数 "です。しかし、この値は "実装定義"であることにも注意してください。だから、技術的なことを知りたければ、C#の仕様は単に "それを理解する"と言います。 IntPtr
のドキュメントは、それがクリアタイプは、32ビットのIntPtr
が対応ビルトインタイプの特殊であることを32ビットプラットフォームおよび64ビット、64ビット・プラットフォーム上の、そしてECMA-335文書上にあることになり、言っ
native int
に変更されていますので、仕様に準拠している実装ではsizeof(IntPtr)
が予測可能であると仮に判断できます.4ビットの32ビットプラットフォームでは8、64ビットプラットフォームでは8です。代わりにIntPtr.Size
があり、それは明示的に書かれています。
Marshal.SizeOf(typeof(IntPtr))
は別の獣です。これは、「アンマネージタイプのサイズ」以外のものが返すものを正確には記述しません。水の下では、CLRのネイティブコードを呼び出して、TypeHelper
にサイズの基礎となる型を問い合わせます。 IntPtr
の場合、これは、C++コンパイラとプラットフォームの大半では、32ビットプラットフォームでは4で、64ビットプラットフォームでは8です(C++で)sizeof(void*)
を返します。
理論的には、理論的には、sizeof(IntPtr)
とMarshal.SizeOf(typeof(IntPtr))
は異なる可能性があります。しかし、ランタイムとジッタ(またはAOTコンパイラ)の組み合わせがsizeof(IntPtr)
をMarshal.SizeOf(typeof(IntPtr))
にしないと賢明ではないので、これはあなたが一般的に心配するものではありません。そうでなければ、ランタイムはただ独自のものです人生はより困難です。一方、私が指摘したように、なぜあなたがに依頼する必要があるのかという理由はありません。も同じです。
一つには、プリミティブ型があります:
| x64 | x86
| Marshal. | Marshal.
Primitive | SizeOf<T>() sizeof(T) | SizeOf<T>() sizeof(T)
========= | =========== =========== | =========== ===========
Boolean | 4 <-> 1 | 4 <-> 1
Byte | 1 1 | 1 1
SByte | 1 1 | 1 1
Int16 | 2 2 | 2 2
UInt16 | 2 2 | 2 2
Int32 | 4 4 | 4 4
UInt32 | 4 4 | 4 4
Int64 | 8 8 | 8 8
UInt64 | 8 8 | 8 8
IntPtr | 8 8 <-> 4 4
UIntPtr | 8 8 <-> 4 4
Char | 1 <-> 2 | 1 <-> 2
Double | 8 8 | 8 8
Single | 4 4 | 4 4
さらに、のstruct(ValueType
)インスタンスの場合、内部管理レイアウトとマーシャリングイメージの間には、合計サイズとフィールドレイアウトの順序の両方に大きな違いがあります。後者は、いわゆるformatted classesでも真です。 は、[1]
それは実際に実際の管理構造体のレイアウトに関する情報を必要とすることはまれだし、実際に.NETはそれを発見でき作ろうとして偉大な長さになります。また、構造体の内部レイアウトに影響を与えることもできません。その理由は、Marshal
レイヤーがinteropに必要なレイアウトを明確に宣言する機能を提供する理由です。
構造体のランタイムメモリイメージの実際のサイズを知る必要があるユースケースです:ある種のストレージBLOBコンセプトに構造体の配列を使用していて、各チャンク(配列)を一定の総割り当てサイズ、たとえば〜84,800バイトの下に留まります。このケースでは明らかにLOHのままです。この記憶域クラスは、「レコード」またはテーブルエントリを定義する任意のValueType
タイプでパラメータ化された汎用クラスにする必要があります。各管理対象配列チャンクに入ることができる構造体の数を判断するには、実行時に与えられた構造体の真のサイズを発見する必要があります。そのため、84,800をその値で割ります。管理・内部構造体のレイアウト、パディング、およびサイズ対をマーシャリングの間に発生する可能性の違いのより詳細な検査のため
は、「How do I check the number of bytes consumed by a structure?」
に私の拡張の回答を参照してください。
[1。] "A フォーマット済みクラスは、レイアウトがStructLayoutAttribute属性で指定された参照タイプで、LayoutKind.ExplicitまたはLayoutKind.Sequentialのいずれかとなります。
https://msdn.microsoft.com/en-us/library/2zhzfk83(v=vs.110).aspx
- 1. ハンドル(IntPtr)kernel32.dll、SafeFileHandle to IntPtr
- 2. IntPtrからIntPtrへデータをコピー
- 3. srp6 IntPtr to BigInteger
- 4. IntPtr to Uint32? C#
- 5. IntPtr to Event
- 6. intptrとは何ですか?
- 7. COMのIntPtrとAs Any Any
- 8. IntPtrの空きメモリ
- 9. C#、IntPtrのデフォルトパラメータ値
- 10. IntPtr常にゼロC#
- 11. Marshal.AllocHGlobal VS Marshal.AllocCoTaskMem、Marshal.SizeOf VSはsizeof()
- 12. フォームのIntPtrが必要(VB.Net)
- 13. C#IntPtrをintに変換する
- 14. IntPtrをSafeHandleに変換するには?
- 15. プロセス/アプリケーション間でIntPtrを渡す方法
- 16. IntPtrが指すメモリの内容をC#
- 17. C#でIntPtrにCodeElementsをマーシャリングする
- 18. Intptrハンドルがガベージコレクトされていない
- 19. IntPtrとMarshal.ReadIntPtrの違いは何ですか?
- 20. C#でIntPtrをint *に変換しますか?
- 21. コールバック内でIntPtrをリリースする必要がありますか?
- 22. VB.netプロジェクトでCOM DLLのIntPtr値を設定する
- 23. IntPtrをstring.Formatの16進文字列に変換
- 24. メソッドが見つかりません「のIntPtr System.Fabric.SecurityCredentialExtension.ToNative
- 25. Unity C#でCOM IntPtrに従う方法は?
- 26. C# - オブジェクトをIntPtrに変換して戻す方法
- 27. IntPtr/IntをSocketに変換するには?
- 28. IntPtrの配列へのポインタの配列を変換する
- 29. C#のulong変数へのIntPtrの取得
- 30. 処理されたキーストローク:IntPtr戻り値の理解
あなたは(64倍)4' 'それはどちらか常に何(32X)を意味または' 8'ますか?あなたは 'IntPtr'構造体がもっと管理されたメモリ(https://ericlippert.com/2013/06/13/whats-the-difference-sizeof-and-marshal-sizeof/)を必要としないのは幸いですいつか、またはプラットフォームによっては、適切なものを使い続ける方がよいでしょう。 – Sinatr
メモリ内のサイズとワイヤのサイズが同じであるかどうかを気にする理由を説明できますか?あなたはトリビアの質問をしているだけですか、またはあなたの質問には何らかの目的がありますか? –
@EricLippert主に、特にIntPtrを念頭に置いて、Marshal.SizeOf()とsizeof()が互換性があるかどうかを調べることが主なポイントでした。もしそうでなければ、なぜ誰かが他のものを使用するのでしょうか? – cogumel0