Что пошло не так с моим заявлением Declare?

Недавно я исправил ошибку в приложении VB6, но я не уверен, что именно пошло не так.

Оскорбительной частью было неправильное объявление API CreateEvent. Вот что сгенерировал API Viewer:

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

Следующим является неверное объявление, очевидно, кто-то не хотел импортировать структуру SECURITY_ATTRIBUTES...

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

Звонок был:

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

Этот вызов работал всегда в IDE, но никогда из скомпилированного .exe. (CreateEvent всегда возвращает 0)

Я изменил объявление на:

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

... и это сработало.

Теперь я немного озадачен:

  • Почему параметр ByRef при использовании SECURITY_ATTRIBUTES должен быть ByVal при использовании Any?
  • Почему неправильное объявление всегда работало в среде IDE?

person Daniel Rikowski    schedule 04.02.2010    source источник
comment
ByVal ... As Any — самый странный случай объявления параметра.   -  person wqw    schedule 06.02.2010


Ответы (1)


Если вы используете неквалифицированный параметр As Any, вы должны указать это в Call. Это должно было решить проблему:

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

Я не понимаю, почему вы должны использовать здесь Nothing, так как это ссылка на объект, а вызов ожидает указатель. Что делает ByVal 0&, так это передает нулевой указатель - поскольку он нулевой, не имеет значения, на что он (не) указывает. Но прохождение Nothing ByVal, вероятно, форсирует ByVal 0&, вот почему это сработало.

Что касается того, почему это работало в IDE, ну, IDE, как правило, более снисходительна к таким вещам.

person Jim Mack    schedule 04.02.2010