Per chiamare un metodo che richiede IntPtr, è meglio usare / non sicuri, o Marshal.AllocHGlobal?

StackOverflow https://stackoverflow.com/questions/1682776

Domanda

Ho una classe che avrà alcuni casi persistenti per tutta la durata dell'applicazione. Questi oggetti ciascun necessario chiamare un metodo DLL che aggiunge dati da un galleggiante [] tampone esistente, e passa l'intero set di dati a un metodo DLL che accetta un IntPtr (matrice float), più volte al secondo. E 'meglio farlo codice come non gestito:



    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);
        }
    }

o sarebbe meglio utilizzare un tag non sicuri e fisso?


    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);
            }
        }
    }

C'è qualche vantaggio di non dover utilizzare il tag "non sicuro" nel compilatore? È la classe Marshal realtà qualsiasi "più sicuro"? Quale di questi metodi generalmente hanno la migliore prestazione?

I magra verso l'ex, proprio perché in questo modo il GC non deve preoccuparsi di _floats (che potrebbe essere abbastanza grande) quando si pulisce lo spazio di memoria. che è una preoccupazione ragionevole? Ha la raccomandazione dipende dalle dimensioni del arraysize?

È stato utile?

Soluzione 2

I definitiva imparato che entrambe le soluzioni vanno bene. Le prestazioni sono circa lo stesso e il GC non avrà un impatto sulla seconda soluzione, dal momento che l'oggetto sarebbe o essere assegnato al mucchio di oggetti di grandi dimensioni e non si mosse, o rapidamente essere promosso al 2 ° generazione sul garbage collector e si è trasferito molto raramente .

Altri suggerimenti

In entrambi i casi, si sta chiamando nativo, il codice non sicuro.

Io preferisco la seconda opzione - è più pulito, più facile da seguire, e più evidente. Inoltre non forzare IDisposable su di voi per l'array da riscuotere.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top