2017-06-22 24 views
1

Goからネイティブライブラリを呼び出す必要があります。GoからNotifyIpInterfaceChangeを呼び出すと、アクセス違反例外が発生する

私は、ネットワークインターフェイスの変更をリスンするためにWindowsライブラリでイベントフックを設定しようとしています。これまでは、リスナーをNotifyAddrChangeに設定して成功しました。今、私は次のコード

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 
} 
コードは罰金コンパイルし、あらゆる問題なく起動

NotifyIpInterfaceChangeにしようとしています

は、問題は、関数が呼び出されると、その後、私は、次の例外を取得起こる

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 

私が知っている例外タイプ0xc0000005は、プログラムが割り当てられていないメモリにアクセスしようとしたときにCPUによってスローされるアクセス違反ですが、私のコードを見れば、渡されたすべてのポインタは、アプリケーション内の項目用です。

ここで助けがあればすばらしくなるでしょう。

答えて

1

は、ドキュメントによると、NotifyIpInterfaceChangeの最新のパラメータは両方in/outあるとHANDLEポインタする必要があります。

ret, _, errNum := procNotifyIpInterfaceChange.Call(syscall.AF_UNSPEC, 
    syscall.NewCallback(callback), 
    uintptr(unsafe.Pointer(context)), 
    0, 
    uintptr(unsafe.Pointer(&interfaceChange))) //this must be pointer 

EDIT::へのシステムコールに変更コメントとthis go-nuts discussionで述べたように
を、マルチスレッドのコールバックのために、import "C"は、私たちがcgoを使用していない場合でも、追加する必要があります。

+0

よろしくお願いいたします。愚かな私は十分な注意を払っていませんでした。 NotifyIpInterfaceChangeはスレッドコールバックであるため、 'import" C "'をインクルードする必要がある点に注意する必要があります。それをあなたの答えに加えるなら、私は受け入れるでしょう –

+1

@LiamHaworth、あなたは正しい、答えが更新されました。 – putu

関連する問題