2010-12-10 19 views
4

Bonjour tous,UInt32 [] par rapport UInt32 *

Je travaille avec l'accès à certaines DLL externes via le InteropServices.DllImport. Je me suis installé à l'origine sur un code dangereux comme suit:

internal extern static unsafe void CreateArray(Int32 size, [OutAttribute] UInt32* array); 

Cependant, je pensais qu'il pourrait être possible de remplacer ce code non sécurisé avec un code purement sécuritaire en passant un tableau UInt32 au lieu d'un pointeur. Le code passe à

internal extern static void CreateArray(Int32 size, [OutAttribute] UInt32[] array); 

qui semble fonctionner sans problème. Cependant, je pèche du côté de la prudence. Est-il possible que le GC arrive maintenant et cause des problèmes? Y at-il une grande différence entre passer un tableau et passer un pointeur UInt32? Y a-t-il des cas d'angle qui me manquent?

Merci pour votre perspicacité,

Giawa

Répondre

4

Ce dernier est très bien. La couche P/Invoke épingle le tableau géré en mémoire pendant l'exécution de CreateArray, et cette approche ne nécessite pas de marshaling, car UInt32[] est un blittable type. Ce sera donc aussi rapide que d'utiliser un pointeur. Avec l'ancienne déclaration, vous deviez soit copier la mémoire dans un tableau géré approprié, à moins que vous alliez opérer entièrement sur la sortie via le pointeur. Et cette copie serait plus chère. Donc, en d'autres termes, si vous essayez d'obtenir un tableau géré correctement hors de l'appel, l'utilisation de cette dernière syntaxe sera plus efficace et n'exigera aucune extraction manuelle des données.

+0

cdhowie, si je comprends bien, modifier la variable 'Uint32 [] array' n'affectera pas les données d'origine? (par exemple, il effectue une copie) –

+0

@pst: Non, la fonction non managée recevra un pointeur sur le début des données du tableau. – cdhowie

+0

Je pensais qu'une solution de rechange serait de prendre un GCHandle et épingler le tableau - mais il est très cool que P/Invoke le fasse pour moi. Merci pour votre réponse! – Giawa