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?