2009-06-26 7 views
11

J'ai quelques fonctions p/invoquées (mais je réécris mon code pour le moment donc je range) et je veux savoir comment utiliser/transmettre un type nullable comme l'un des paramètres. travailler avec les types int est pas un problème mais étant donné les éléments suivants:Comment passer un type Nullable à une fonction P/invoquée

[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, int? enumerator, IntPtr hwndParent, uint Flags); 

Je voudrais pouvoir passer le paramètre Guid comme un type nullable. Comme il se trouve au moment où je peux l'appeler comme:

SetupDiGetClassDevs(ref tGuid, null, IntPtr.Zero, (uint)SetupDiFlags.DIGCF_PRESENT); 

mais je dois le premier paramètre à être aussi passable comme null.

+1

@River mine Voici pas la question incriminée comme cela a été demandé retour en 2009;) –

+0

la nouvelle est une tentative de créer une version canonique de cette problème, avec plus de solutions qui sont plus générales. – River

Répondre

11

Il n'est pas possible de passer un type Nullable dans une fonction PInvoke'd sans une ... manipulation d'octets intéressante dans le code natif qui n'est certainement pas ce que vous voulez.

Si vous avez besoin la possibilité de transmettre une valeur NULL struct en code natif déclarer une surcharge de votre déclaration PInvoke qui prend un IntPtr à la place de la struct et passer IntPtr.Zero

[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, ref int enumerator, IntPtr hwndParent, uint Flags); 
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, IntPtr enumerator, IntPtr hwndParent, uint Flags); 

Note: J'ai ajouté une classe ref à la première signature. Si la signature native peut prendre NULL, il s'agit probablement d'un type de pointeur. Par conséquent, vous devez passer des types de valeur par référence.

Maintenant, vous pouvez faire des appels comme le

if (enumerator.HasValue) { 
    SetupDiGetClassDevs(someGuid, ref enumerator.Value, hwnd, flags); 
} else { 
    SetupDiGetClassDevs(someGuid, IntPtr.Zero, hwnd, flags); 
} 
+1

J'ai surchargé mes fonctions P/invoke jusqu'ici. Ma question était de voir si je pourrais raccourcir ceci et ranger mon code plus en n'ayant pas besoin de surcharger. Jusqu'à présent, j'ai été en mesure de passer int (paramètre 2) comme une valeur NULL sans problèmes cela signifie-t-il que cette restriction ne s'applique qu'aux types structurés? Une autre chose dans une incarnation de mon code j'ai défini le paramètre 2 comme '[MarshalAs (UnmanagedType.LPTStr)] chaîne Enumerator' qui me permet également d'annuler ce paramètre pendant l'utilisation. –

+0

Mes excuses ... Je ne peux pas m'en tirer avec un int nullable :) –

Questions connexes