我的 Declare 声明出了什么问题?
我最近修复了 VB6 应用程序中的一个错误,但我不确定到底出了什么问题。
有问题的部分是 CreateEvent
的错误 API 声明。这是 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
...并且它起作用了。
现在我有点困惑:
- 为什么使用
SECURITY_ATTRIBUTES
时参数是ByRef
,而使用AnyByVal
代码>? - 为什么错误的声明总是在 IDE 中起作用?
I've recently fixed a bug in a VB6 application, but I'm not sure, what exactly went wrong.
The offending part was a wrong API declaration of CreateEvent
. This is, what API Viewer generated:
Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA"
(lpEventAttributes As SECURITY_ATTRIBUTES, ...) As Long
The next one is the wrong declare, obviously someone didn't want to import the SECURITY_ATTRIBUTES
structure...
Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA"
(lpEventAttributes As Any, ...) As Long
The call was:
Event = CreateEvent(Nothing, 0, 0, "MyEventName")
This call worked always in the IDE, but never from the compiled .exe. (CreateEvent
always returned 0)
I changed the declaration to:
Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA"
(ByVal lpEventAttributes As Any, ...) As Long
... and it worked.
Now I'm a little bit puzzled:
- Why is the parameter
ByRef
when usingSECURITY_ATTRIBUTES
but must beByVal
when usingAny
? - Why did the wrong declare always work in the IDE?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您使用不合格的 As Any 参数,则必须在调用中明确显示。这应该可以解决问题:
我不明白为什么你会在这里使用
Nothing
,因为那是一个对象引用,并且调用需要一个指针。ByVal 0&
的作用是传递一个空指针——因为它是空的,所以它指向(不)指向什么并不重要。但是传递Nothing ByVal
可能会强制ByVal 0&
,这就是它起作用的原因。至于为什么它在 IDE 中有效,嗯,IDE 确实对此类事情更加宽容。
If you use an unqualified As Any parameter, you have to be explicit in the Call. This should have fixed the problem:
I can't see why you'd use
Nothing
here, since that's an Object reference and the call is expecting a pointer. WhatByVal 0&
does is pass a null pointer -- since it's null it doesn't matter what it's (not) pointing to. But passingNothing ByVal
probably forcesByVal 0&
, which is why it worked.As to why it worked in the IDE, well, the IDE does tend to be more forgiving about things like this.