Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 从Go调用NotifyIpInterfaceChange导致访问冲突异常_Windows_Exception_Go_Dll_System Calls - Fatal编程技术网

Windows 从Go调用NotifyIpInterfaceChange导致访问冲突异常

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

这是我第一次不得不从Go打电话到本机库

我正在尝试使用windows库设置事件挂钩以侦听网络接口更改,到目前为止,我已成功地使用设置了侦听器

现在,我正在使用以下代码尝试
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包含在线程回调中。如果你把这个加在你的答案上,我会接受的