2009-11-05 18 views
0

J'ai une classe qui aura quelques instances persistantes pendant toute la durée de l'application. Ces objets auront chacun besoin d'appeler une méthode dll qui ajoute des données à partir d'un tampon float [] existant, et passe l'ensemble de données complet à une méthode DLL qui accepte un IntPtr (tableau flottant), plusieurs fois par seconde. Est-il préférable de le faire en tant que code non managé:Pour appeler une méthode nécessitant IntPtr, est-il préférable d'utiliser/unsafe, ou Marshal.AllocHGlobal?



    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 serait-il préférable d'utiliser une étiquette dangereuse et fixe? Y at-il un avantage de ne pas avoir à utiliser la balise "dangereuse" dans le compilateur?


    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); 
      } 
     } 
    } 
La classe des maréchaux est-elle réellement "plus sûre"? Lesquelles de ces méthodes ont généralement les meilleures performances?

Je penche pour le premier, juste parce que de cette façon, le GC n'a pas à se soucier de _floats (ce qui pourrait être assez grand) lors du nettoyage de l'espace mémoire. Est-ce une préoccupation raisonnable? Est-ce que la recommandation dépend de la taille de ArraySize?

Répondre

2

J'ai finalement appris que les deux solutions sont bien. La performance est à peu près la même et le GC n'aura pas d'impact sur la 2ème solution, puisque l'objet serait soit affecté au Large Object Heap et jamais déplacé, soit rapidement promu à la 2nde génération sur le garbage collector et déplacé très rarement .

3

Dans les deux cas, vous appelez un code natif et non sécurisé.

Je préfère la deuxième option - elle est plus propre, plus facile à suivre et plus évidente. Cela ne force pas IDisposable sur vous pour que votre tableau soit collecté.