【问题标题】:Go language use internal structures from CGo 语言使用 C 的内部结构
【发布时间】:2017-01-18 20:30:14
【问题描述】:

我希望能够在 Go 中将一个主机地址(让我们使用“www.google.be”)转换为 sockaddr 结构,然后从 C 代码中使用它。

使用http://github.com/jbenet/go-sockaddr 模块将主机地址转换为 sockaddr_any 结构并不难。我的代码有效,如下所示:

ipAddr, _ := net.ResolveIPAddr("ip", "www.google.be")
sockAddr := sockaddrnet.IPAddrToSockaddr(ipAddr)
rawSockaddr, socklen, _ := sockaddr.SockaddrToAny(sockAddr)
cStruct := sockaddr.AnyToCAny(rawSockaddr)
C.printPointer(cStruct)

但是,我不能从我的 C 代码中使用这个 *sockaddr.C.struct_sockaddr_any 变量:cStruct(它的定义不完整,所以我不能使用它的任何字段),如下所示:

// #include <stdio.h>
// void printPointer(struct sockaddr_any *p){
//     printf(":: %p :: ", p); 
//     // How to use P as a sockaddr? 
// }
import "C"

sockaddr_any 在 Go 语言的核心中定义(来自 https://golang.org/src/syscall/types_linux.go)。所以,我相信它应该默认与我的 C 代码链接。但是,这似乎不是真的。有人知道我可以使用哪一行来包含 go 语言本身的标头(这里是系统调用结构)。

非常感谢

【问题讨论】:

    标签: c linux networking go system-calls


    【解决方案1】:

    你可以使用 struct sockaddr*:

    void printPointer(struct sockaddr_any *pp) {
        struct sockaddr *p = pp->addr;
        printf(":: %p :: ", p); 
    }
    

    因为 sockaddr_any 被定义为:

    struct sockaddr_any {
       struct sockaddr addr;
       char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
    };
    

    【讨论】:

    • 感谢您的回答。但是,它似乎不起作用。 Go 告诉我cannot use cStruct (type *sockaddr.C.struct_sockaddr_any) as type *C.struct_sockaddr in argument to _Cfunc_printPointer。如果可能的话,我想避免 unsafe.Pointer 。你有其他想法可以帮助我吗?非常感谢
    • 好吧,那就保留原来的函数签名void printPointer(struct sockaddr_any*),如图所示在四个C代码中声明struct sockadr_any,然后访问.addr。
    • 事实上这是不可能使用 addr 字段的,因为 sockaddr_any 的类型不完整(我无法找到标题);但随着类型转换的工作,问题得到解决:)
    【解决方案2】:

    使用 Laszlo 答案,我的问题有一个简单的解决方案。并不是因为在我的上下文中无法访问结构 sockaddr_any 的定义(没有简单的方法可以访问 addr 字段),我们不能转换指针。所以,我可以简单地做:

    // #include <stdio.h>
    // void printPointer(struct sockaddr_any *p){
    //     struct sockaddr *usable_pointer = (struct sockaddr *) p; 
    // }
    import "C"
    

    然后,我可以将usable_pointer 用作任何其他sockaddr 变量。

    非常感谢

    【讨论】:

    • 不客气。这也是我的第一个想法,但想避免类型转换。
    猜你喜欢
    • 1970-01-01
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    相关资源
    最近更新 更多