Windows 从Go调用NotifyIpInterfaceChange导致访问冲突异常
这是我第一次不得不从Go打电话到本机库 我正在尝试使用windows库设置事件挂钩以侦听网络接口更改,到目前为止,我已成功地使用设置了侦听器 现在,我正在使用以下代码尝试Windows 从Go调用NotifyIpInterfaceChange导致访问冲突异常,windows,exception,go,dll,system-calls,Windows,Exception,Go,Dll,System Calls,这是我第一次不得不从Go打电话到本机库 我正在尝试使用windows库设置事件挂钩以侦听网络接口更改,到目前为止,我已成功地使用设置了侦听器 现在,我正在使用以下代码尝试NotifyIpInterfaceChange package main import ( "golang.org/x/sys/windows" "log" "syscall" "unsafe" ) var ( modiphlpapi = windows.NewLazySystemDL
NotifyIpInterfaceChange
package main
import (
"golang.org/x/sys/windows"
"log"
"syscall"
"unsafe"
)
var (
modiphlpapi = windows.NewLazySystemDLL("iphlpapi.dll")
procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange")
)
type context struct{}
func main() {
log.Printf("Loaded [iphlpapi.dll] at {%#v}", modiphlpapi.Handle())
log.Printf("Found [NotifyIpInterfaceChange] at {%#v}", procNotifyIpInterfaceChange.Addr())
context := &context{}
interfaceChange := windows.Handle(0)
ret, _, errNum := procNotifyIpInterfaceChange.Call(syscall.AF_UNSPEC, syscall.NewCallback(callback), uintptr(unsafe.Pointer(context)), 0, uintptr(interfaceChange))
log.Printf("%#v %#v", ret, errNum)
}
func callback(callerContext, row, notificationType uintptr) uintptr {
log.Printf("callback invoked by Windows API (%#v %#v %#v)", callerContext, row, notificationType)
return 0
}
代码编译良好,启动时没有任何问题,一旦调用函数,问题就会发生,然后我得到以下异常
D:\>event-listen_type2.exe
2017/06/22 22:12:39 Loaded [iphlpapi.dll] at {0x7ffac96f0000}
2017/06/22 22:12:39 Found [NotifyIpInterfaceChange] at {0x7ffac96f7e20}
Exception 0xc0000005 0x1 0x0 0x7ffac96f7edb
PC=0x7ffac96f7edb
syscall.Syscall6(0x7ffac96f7e20, 0x5, 0x0, 0x454170, 0x54d360, 0x0, 0x0, 0x0, 0xc042015350, 0xc042015300, ...)
/usr/local/Cellar/go/1.8.3/libexec/src/runtime/syscall_windows.go:174 +0x6b
github.com/LiamHaworth/windows-network-events/vendor/golang.org/x/sys/windows.(*Proc).Call(0xc04203a620, 0xc042050300, 0x5, 0x5, 0x30, 0x4b12e0, 0x1, 0xc042050300)
/Users/liam/git/go_path/src/github.com/LiamHaworth/windows-network-events/vendor/golang.org/x/sys/windows/dll_windows.go:139 +0x5c1
github.com/LiamHaworth/windows-network-events/vendor/golang.org/x/sys/windows.(*LazyProc).Call(0xc042050270, 0xc042050300, 0x5, 0x5, 0x1, 0xc04201a000, 0xc04202df78, 0x4043a3)
/Users/liam/git/go_path/src/github.com/LiamHaworth/windows-network-events/vendor/golang.org/x/sys/windows/dll_windows.go:309 +0x66
main.main()
/Users/liam/git/go_path/src/github.com/LiamHaworth/windows-network-events/main_windows.go:25 +0x229
rax 0x0
rbx 0xc3f10
rcx 0x1fb5cd87abfd0000
rdi 0x0
rsi 0x454170
rbp 0xc04202dc00
rsp 0x8fdf0
r8 0x8fb78
r9 0x7ffac96fb4c0
r10 0x0
r11 0x8fcf0
r12 0x0
r13 0xffffffee
r14 0x0
r15 0xaa
rip 0x7ffac96f7edb
rflags 0x10246
cs 0x33
fs 0x53
gs 0x2b
通过一些谷歌搜索,我知道异常类型0xc000005
是当程序试图访问未分配给它的内存时,CPU抛出的一种访问冲突,但查看我的代码时,我不知道发生了什么。传递的所有指针都用于应用程序中的项
这里的任何帮助都将是伟大的 根据文档,的最新参数既是
in/out
,又需要是指向句柄的指针。将系统调用更改为:
ret, _, errNum := procNotifyIpInterfaceChange.Call(syscall.AF_UNSPEC,
syscall.NewCallback(callback),
uintptr(unsafe.Pointer(context)),
0,
uintptr(unsafe.Pointer(&interfaceChange))) //this must be pointer
编辑:
如注释中所述,对于多线程回调,需要添加导入“C”
,即使我们不使用cgo
是的,您在这里是正确的。愚蠢的我没有引起足够的注意。另一件需要注意的事情是,import“C”
必须作为NotifyIpInterfaceChange包含在线程回调中。如果你把这个加在你的答案上,我会接受的