Go语言使用C语言的内部结构。

huangapple go评论94阅读模式
英文:

Go language use internal structures from C

问题

我想要在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(它的定义不完整,所以我无法使用它的任何字段)。我的C代码如下:

// #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语言本身的头文件(这里是syscall结构)吗?

非常感谢!

英文:

I would like to be able, in Go, to translate one host address (let's use 'www.google.be') to a sockaddr structure and then use it from a C code.

Translating the host address to a sockaddr_any structure isn't too hard using the http://github.com/jbenet/go-sockaddr module. My code works and is the following:

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

But, I'm not able to use this *sockaddr.C.struct_sockaddr_any variable: cStruct, from my C code (it has incomplete definition, so I can't use any of its fields), which is the following:

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

sockaddr_any is defined in the core of the Go language (from https://golang.org/src/syscall/types_linux.go). So, I believe it should be linked by default with my C code. But, it seems not to be true. Does someone know what line could I use to include headers from the go language itself (here the syscall structures).

Thank you very much

答案1

得分: 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)];
};
英文:

You can use struct sockaddr*:

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

since sockaddr_any is defined as:

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

答案2

得分: 0

使用Laszlo的答案,我对我的问题有一个简单的解决方案。尽管在我的上下文中无法访问结构sockaddr_any的定义(没有简单的方法来访问addr字段),但我们仍然可以进行指针转换。因此,我可以简单地这样做:

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

然后,我可以像使用其他sockaddr变量一样使用usable_pointer

非常感谢。

英文:

Using Laszlo answer, there is a simple solution for my problem. It isn't because the definition of the structure sockaddr_any isn't accessible in my context (there's no simple way to access the addr field) that we can't cast the pointer. So, I can simply do:

// #include &lt;stdio.h&gt;
// void printPointer(struct sockaddr_any *p){
//     struct sockaddr *usable_pointer = (struct sockaddr *) p; 
// }
import &quot;C&quot;

Then, I can use usable_pointer as any other sockaddr variable.

Thank you very much

huangapple
  • 本文由 发表于 2017年1月19日 04:30:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/41728874.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定