IntPtrを必要とするメソッドを呼び出すには、/ unsafe、またはMarshal.AllocHGlobalのいずれを使用するのが良いでしょうか。

c# fixed intptr marshalling unsafe
IntPtrを必要とするメソッドを呼び出すには、/ unsafe、またはMarshal.AllocHGlobalのいずれを使用するのが良いでしょうか。

私は、アプリケーションの間ずっといくつかのインスタンスが持続するクラスを持っています。 これらのオブジェクトはそれぞれ、既存のfloat []バッファからデータを追加し、フルデータセットをIntPtr(float配列)を受け入れるDLLメソッドに1秒間に数回渡すdllメソッドを呼び出す必要があります。 管理されていないコードとして実行する方が良いでしょうか。

    class PersistentThing : IDisposable {
        readonly IntPtr _floats = Marshal.AllocHGlobal(sizeof(float) * ArraySize);

        public void DoFrequentAction() {
            // Append data from a buffer to the memory space.
            var floatOffsetPtr = new IntPtr(_floats.ToInt32() + _floatsIndex * sizeof(float));
            Marshal.Copy(_buffer, _bufferIndex, floatOffsetPtr, _bufferCount);

            // Call a DLL method with with memory pointer
            CallDllMethod(_floats);
        }

        // Need to dispose the unmanaged memory
        public void Dispose() {
            Marshal.FreeHGlobal(_floats);
        }
    }

それとも安全でないタグを使用して修正したほうがよいでしょうか。

    class PersistentThing2 {
        readonly float[] _floats = new float[ArraySize];

        public unsafe void DoFrequentAction() {
            // Append data from a buffer to the memory space.
            Array.Copy(_buffer, _bufferIndex, _floats, _floatsIndex, _bufferCount);

            // Call a DLL method with with memory pointer
            fixed (float* floatsPtr = _floats) {
                CallDllMethod((IntPtr)floatsPtr);
            }
        }
    }

コンパイラで「安全でない」タグを使用する必要がないという利点はありますか? 元帥階級は実際には「より安全」ですか? これらの方法のどれが一般により良いパフォーマンスを持っていますか?

私が前者に傾いているのは、そのようにしてメモリ空間をクリーンアップするときにGCが _floats(これはかなり大きいかもしれない)を心配する必要がないからです。 それは妥当な懸念ですか? 推奨はArraySizeのサイズによって異なりますか?

  0  0


ベストアンサー

どちらの場合も、あなたはネイティブで危険なコードを呼び出しています。

私は2番目の選択肢を好む – それはより清潔で、従うのがより簡単で、そしてより明白である。 アレイを収集するためにIDisposableを強制することもありません。

3


私は最終的に両方の解決策がうまくいくことを学びました。 オブジェクトはラージオブジェクトヒープに割り当てられて移動されないか、ガベージコレクタですぐに第2世代に昇格されて移動されることはほとんどないため、パフォーマンスはほぼ同じで、GCは第2のソリューションに影響を与えません。 。

2


タイトルとURLをコピーしました