Para chamar um método que requer IntPtr, é melhor usar / inseguro, ou Marshal.AllocHGlobal?

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

Pergunta

Eu tenho uma classe que terá algumas instâncias persistentes durante toda a duração da aplicação. Estes objectos serão cada necessidade de chamar um método dll que acrescenta dados a partir de um flutuador existente [] tampão, e passa o conjunto de dados completo com um método DLL que aceita um (matriz de flutuador) IntPtr, várias vezes por segundo. É melhor fazê-lo como código não gerenciado:



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

ou seria melhor usar um tag inseguro e fixo?


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

Existe alguma vantagem de não ter que usar a tag "inseguro" no compilador? É a classe Marshal, na verdade, qualquer "mais seguro"? Qual destes métodos geralmente têm o melhor desempenho?

Eu me inclino para o primeiro, só porque dessa forma o GC não tem que se preocupar com _floats (que poderia ser muito grande) ao limpar o espaço de memória. É que uma preocupação razoável? A recomendação dependerá do tamanho da ArraySize?

Foi útil?

Solução 2

I última análise, aprendi que ambas as soluções são muito bem. O desempenho é quase o mesmo eo GC não terá um impacto sobre a segunda solução, uma vez que o objeto teria quer ser alocado para o objeto grande Heap e nunca mudou, ou ser rapidamente promovido a 2ª geração do coletor de lixo e se mudou muito raramente .

Outras dicas

Em ambos os casos, você está chamando código nativo, inseguro.

Eu prefiro a segunda opção - é mais limpo, mais fácil de seguir, e mais óbvia. Ele também não forçar IDisposable em você para sua matriz para ser coletado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top