2009-09-15 5 views
7

Lorsque je crée une signature qui fait référence à user32.dll par exemple devrais-je construire ceci avec user64.dll si la cible est un ordinateur 64 bits?Est-ce que P/Invoke sur les fenêtres 64 bits nécessite des signatures différentes que sur 32 bits?

[DllImport("user32.dll", CharSet = CharSet.Auto)] 
public static extern bool ChangeClipboardChain(
    IntPtr hWndRemove, 
    IntPtr hWndNewNext); 

Actuellement, ce n'est pas un problème car je cible 32 bits en raison d'une bibliothèque d'un fournisseur (Progress OpenEdge) qui fournissent uniquement les bibliothèques 32 bits pour accéder à leur base de données.

Je n'ai actuellement pas d'ordinateur Windows 64 bits pour voir si c'est le cas.

Répondre

12

Malgré la convention de dénomination, user32.dll (et 32 ​​autres dlls) sont en fait 64 bits sur des machines 64 bits. Ce sont les noms d'historique pour les DLL, et ont été conservés de cette façon indépendamment des changements apportés à l'architecture sous-jacente. Avoir une lecture de this page pour obtenir plus de détails.

+1

Mon Dieu merci, la façon dont cette page décrit comment les changements de vue des systèmes de fichiers entre les applications 64/32 bits est plutôt effrayant à voir. Merci beaucoup pour votre réponse Pete. –

+0

De rien. Je suis heureux d'aider. –

5

Vous devez pas devez modifier la signature/le nom de la DLL que vous liez à lors de l'appel aux fonctions USER32.DLL.

Malgré la convention de dénomination, sur un ordinateur Windows 64 bits, le fichier USER32.DLL qui se trouve dans [Windows] \ System32 est en fait une DLL 64 bits. Le réel version 32 bits de USER32.DLL se trouve réellement dans un dossier appelé [Windows] \ SysWow64. Pour plus d'informations, veuillez consulter le this question.

La chose dont vous devrez probablement faire particulièrement attention est celle des types de données que vous transmettez en tant que paramètres aux diverses fonctions de l'API Windows. Par exemple, la fonction "SendMessage" dans USER32.DLL a une exigence spécifique avec au moins un de ses paramètres (selon le page on P/Invoke).

Il est la signature est:

[DllImport("user32.dll", CharSet = CharSet.Auto)] 
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); 

et note 2 ci-dessous & 3 clairement:

2) Ne JAMAIS utiliser "int" ou "entier" comme lParam. Votre code va planter sur Windows 64 bits . Utilisez UNIQUEMENT IntPtr, une structure "ref" , ou une structure "out".

3) N'utilisez JAMAIS "bool", "int", ou "entier" comme valeur de retour. Votre noyau va planter sur les fenêtres 64 bits. Utilisez UNIQUEMENT IntPtr. Il n'est pas sûr d'utiliser bool - pInvoke ne peut pas marshaler un IntPtr à un booléen.

Cette « mise en garde » semble être spécifique à cette fonction particulière (SendMessage), bien que ce soit quelque chose que je voudrais accorder une attention particulière au moment où la remise en toutes les fonctions de l'API Windows.

+0

Merci pour ce Craig, c'est génial. J'ai une question, pourquoi 'System.Windows.Forms.Message.Msg' a un type' int'.Seulement demander parce que cela serait utilisé dans 'Msg' pour' SendMsg', auparavant dans cette même signature j'avais utilisé 'int'. –

+1

@Brett - C'est une bonne question, et je ne connais pas la réponse exacte, cependant, cela peut être dû au fait que la signature SendMessage prend le paramètre Msg comme UInt32, et un .NET Int est toujours 32 bits (indépendamment de plate-forme Windows sous-jacente), tandis qu'une structure IntPtr est conçue pour refléter la plate-forme Windows sous-jacente (c'est-à-dire une structure 32 bits sur Windows 32 bits, mais une structure 64 bits sur Windows 64 bits). Doit admettre, c'est juste une supposition en mon nom. Je serais intéressé de connaître la réponse exacte moi-même. – CraigTP

+0

Oui, j'ai pensé ça; ce qui est intéressant, cependant, c'est que c'est un 'int' et pas un' uint' car 'UInt32' et' Int32' ont des limites supérieure/inférieure différentes, cependant, quiconque envoie quelque chose en dehors de 0 - Int32.MaxValue serait en erreur en tous cas. Juste une observation vraiment :) –

Questions connexes