0

この 2 年前の投稿でFredrik Mörkの回答にコメントを投稿するのは公平だとは思わなかったので、代わりに新しい質問として質問したいと思いました...

注意: これは決して答えの批判ではありません.メモリ管理/マーシャルクラスを掘り下げる前に、これをすべて理解しようとしています.

その答えでは、関数GetByteArrayは、ループ内で、指定された配列内の各オブジェクトにメモリを割り当てます。

前述の投稿の GetByteArray 関数は、提供された配列の合計サイズにメモリを割り当てることでまったく恩恵を受けましたか?

Dim arrayBufferPtr = Marshal.AllocHGlobal(Marshal.SizeOf(<arrayElement>) * <array>.Count)

答えに示されているように、メモリを割り当てると、何らかの断片化が発生するのではないでしょうか? 断片化があると仮定すると、懸念すべき影響は多くありますか? 私が示した方法でメモリを割り当てると、IntPtr.ToInt## を呼び出して全体的な割り当てポインターからポインター オフセットを取得する必要があるため、基礎となるアーキテクチャをチェックして、正しいメソッドが使用されていることを確認する必要があります*1またはより良い方法はありますか?(x86/64 によっては ToInt32/ToInt64?)

*1 間違った IntPtr.ToInt## を呼び出すとオーバーフロー例外が発生することをどこかで読みました。そのステートメントで私が意味することは、私が使用するだろうということです:

Dim anOffsetPtr As New IntPtr(arrayBufferPtr.ToInt## + (loopIndex * <arrayElementSize>))

VB.Net Marshal クラスとメモリ割り当てに関するいくつかの記事を読みました。以下にリストされていますが、他の良い記事を知っていれば、私はすべて耳にします!

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.aspx

http://www.dotnetbips.com/articles/44bad06d-3662-41d3-b712-b45546cd8fa8.aspx

これまでの私のお気に入り: http://www.codeproject.com/KB/vb/Marshal.aspx

4

1 に答える 1

2

配列全体にアンマネージ メモリを割り当ててから、SizeOf(arrayElement)*loopIndex オフセットを使用してすべての配列要素をコピーすることができます。次のように、現在のプラットフォームに応じて、適切な ToInt32/ToInt64 メソッドを使用することをお勧めします。

Dim anOffsetPtr
arrayBufferPtr.Size = 4 の場合
    anOffsetPtr = New IntPtr(arrayBufferPtr.ToInt32() + (loopIndex * arrayElementSize))
そうしないと
    anOffsetPtr = New IntPtr(arrayBufferPtr.ToInt64() + (loopIndex * arrayElementSize))
終了
于 2011-06-14T14:19:25.573 に答える