2010-02-04 25 views
1

J'ai récemment corrigé un bug dans une application VB6, mais je ne suis pas sûr, ce qui s'est mal passé.Qu'est-ce qui n'a pas fonctionné avec ma déclaration Declare?

La partie incriminée était une déclaration d'API incorrecte de CreateEvent. Ceci est, ce que l'API Viewer généré:

Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" 
(lpEventAttributes As SECURITY_ATTRIBUTES, ...) As Long 

Le prochain est la mauvaisedéclare, évidemment quelqu'un ne voulait pas importer la structure SECURITY_ATTRIBUTES ...

Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" 
(lpEventAttributes As Any, ...) As Long 

L'appel a été:

Event = CreateEvent(Nothing, 0, 0, "MyEventName") 

Cet appel a travaillé toujours dans l'IDE, mais jamais à partir du fichier .exe compilé. (CreateEvent toujours retourné 0)

J'ai changé la déclaration:

Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" 
(ByVal lpEventAttributes As Any, ...) As Long 

... et cela a fonctionné.

Maintenant, je suis un peu perplexe:

  • Pourquoi le paramètre ByRef lors de l'utilisation SECURITY_ATTRIBUTES mais doit être ByVal lors de l'utilisation Any?
  • Pourquoi la déclaration incorrecte fonctionne-t-elle toujours dans l'EDI?
+0

'ByVal ... As Any' est le cas le plus bizarre de déclaration de paramètres. – wqw

Répondre

3

Si vous utilisez un paramètre As Any non qualifié, vous devez être explicite dans l'appel. Cela aurait dû fixer le problème:

Event = CreateEvent (ByVal 0 &, 0, 0, "MyEventName")

Je ne vois pas pourquoi vous utilisez Rien ici, puisque c'est une référence d'objet et l'appel attend un pointeur. Ce que ByVal 0 & fait est de passer un pointeur nul - puisqu'il est nul, peu importe ce à quoi il ne pointe pas. Mais passer Nothing ByVal force probablement ByVal 0 &, ce qui explique pourquoi cela a fonctionné. Pour ce qui est de savoir pourquoi cela a fonctionné dans l'EDI, eh bien, l'IDE a tendance à être plus indulgent à propos de choses comme ça.