golang下,调用Win的API,DnsQueryConfig,一直不成功,高手可以指点一下么【已解决,代码在文章结尾】

huangen · · 751 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

DnsQueryConfig,此API的功能是,获取本机的DNS,API的官方文档在这: ``` https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsqueryconfig ``` 在项目`github.com/kbinani/win`下新建了文件`dnsapi.go`,代码如下: ```go // This file was automatically generated by https://github.com/kbinani/win/blob/generator/internal/cmd/gen/gen.go // go run internal/cmd/gen/gen.go // +build windows package win import "unsafe" var ( // Library libdnsapi uintptr // function dnsQueryConfig uintptr ) type DNS_CONFIG_TYPE uint32 type IP4_ARRAY struct { AddrCount DWORD IP4_ADDRESS [0]IP_ADDRESS_STRING } type PIP4_ARRAY *IP4_ARRAY func init(){ // Library libdnsapi = doLoadLibrary("Dnsapi.dll") // Functions dnsQueryConfig = doGetProcAddress(libdnsapi, "DnsQueryConfig") } func DnsQueryConfig(config DNS_CONFIG_TYPE, flag DWORD, pwsAdapterName PCWSTR, pReserved PVOID, pBuffer PVOID, pBufLen DWORD_PTR) int32 { ret1 := syscall6(dnsQueryConfig, 6, uintptr(unsafe.Pointer(&config)), uintptr(unsafe.Pointer(&flag)), uintptr(unsafe.Pointer(pwsAdapterName)), uintptr(pReserved), uintptr(pBuffer), uintptr(unsafe.Pointer(pBufLen)), ) return int32(ret1) } ``` 在自己的项目中,代码如下: ```go package main import ( "fmt" "github.com/kbinani/win" "unsafe" ) func main(){ // func DnsQueryConfig(config DNS_CONFIG_TYPE, flag DWORD, pwsAdapterName PCWSTR, pReserved PVOID, pBuffer PVOID, pBufLen DWORD_PTR) int32 { config := win.DNS_CONFIG_TYPE(6) flag := win.DWORD(0) pwsAdapterName := win.PCWSTR(nil) pReserved := win.PVOID(unsafe.Pointer(nil)) buffer := win.IP4_ARRAY{} a := win.PVOID(unsafe.Pointer(&buffer)) l := uint32(unsafe.Sizeof(buffer)) pBufLen := win.DWORD_PTR(unsafe.Pointer(&l)) //bufferp := win.From r := win.DnsQueryConfig(config, flag, pwsAdapterName, pReserved, a, pBufLen) fmt.Println(r) } ``` 运行的结果始终返回代码87: ```shell 87 Process finished with exit code 0 ``` 我查了下此87代表的意思是`无效的参数`: ```c++ #define ERROR_INVALID_PARAMETER 87L ``` 还请大神指点,哪儿出错了,非常感谢 ----- 这个问题解决了: ```go package main import ( "fmt" "golang.org/x/sys/windows" "net" "strings" "unsafe" ) const ( DnsConfigDnsServerList int32 = 6 ) type char byte type IpAddressString struct { DNS [4 * 10]char } type Ip4Array struct { AddrCount uint32 Ip4Address [1]IpAddressString } func main() { fmt.Println(dns()) } func dns() []string { dns := []string{} dnsapi := windows.NewLazyDLL("Dnsapi.dll") dnsQuery := dnsapi.NewProc("DnsQueryConfig") bufferBytes := make([]byte, 60) loop: buffer := (*Ip4Array)(unsafe.Pointer(&bufferBytes[0])) blen := len(bufferBytes) r1, _, _ := dnsQuery.Call(uintptr(DnsConfigDnsServerList), uintptr(0), uintptr(0), uintptr(0), uintptr(unsafe.Pointer(&bufferBytes[0])), uintptr(unsafe.Pointer(&blen))) if r1 == 234 { bufferBytes = make([]byte, blen) goto loop } else if r1 == 0 { } else { return dns } for i := uint32(1); i <= buffer.AddrCount; i++ { right := i * 4 left := right - 4 tmpChars := buffer.Ip4Address[0].DNS[left:right] tmpStr := []string{} for j := 0; j < len(tmpChars); j++ { tmpStr = append(tmpStr, fmt.Sprint(tmpChars[j])) } tmpDNS := strings.Join(tmpStr, ".") pDns := net.ParseIP(tmpDNS) if pDns == nil { continue } if !pDns.IsGlobalUnicast() { continue } dns = append(dns, tmpDNS) } return dns } ``` 运行结果: ``` [10.198.1.1 114.114.114.114 114.114.115.115 8.8.8.8 218.85.157.99 218.85.152.99] ```

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

751 次点击  
加入收藏 微博
1 回复  |  直到 2020-05-02 16:21:35
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传