2017-01-18 1 views
0

Ich möchte in Go in der Lage sein, eine Host-Adresse (verwenden wir "www.google.be") zu einer Sockaddr-Struktur und dann verwenden Sie es aus einem C-Code.Gehen Sprache verwenden interne Strukturen von C

Das Übersetzen der Host-Adresse in eine sockaddr_any-Struktur ist nicht schwer mit dem http://github.com/jbenet/go-sockaddr Modul. Mein Code funktioniert und ist die folgende:

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

Aber, ich bin nicht in der Lage diese *sockaddr.C.struct_sockaddr_any Variable zu verwenden: cStruct, von meinem C-Code (es hat unvollständige Definition, also kann ich nichts von seinen Feldern verwenden), das die folgenden:

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

sockaddr_any in den Kern der Go-Sprache definiert wird (von https://golang.org/src/syscall/types_linux.go). Also, ich glaube, es sollte standardmäßig mit meinem C-Code verknüpft sein. Aber es scheint nicht wahr zu sein. Weiß jemand, welche Zeile ich verwenden könnte, um Header aus der go-Sprache selbst (hier die Syscall-Strukturen) aufzunehmen.

Vielen Dank

Antwort

1

Sie struct sockaddr * verwenden:

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

seit sockaddr_any wie folgt definiert:

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

Vielen Dank für Ihre Antwort. Aber es scheint nicht zu funktionieren. Go sagt mir 'kann nicht cStruct (type * sockaddr.C.struct_sockaddr_any) als Typ * C.struct_sockaddr im Argument zu _Cfunc_printPointer' verwenden. Ich möchte vermeiden, unsicher. Pointer wenn möglich. Hast du eine andere Idee, mir zu helfen? Vielen Dank –

+0

Nun, dann behalten Sie die ursprüngliche Funktion Unterschrift void printPointer (struct sockaddr_any *), deklarieren struct sockadr_any in vier C-Code wie gezeigt und dann Zugriff .addr. – Laszlo

+0

In der Tat ist es unmöglich, das addr-Feld zu verwenden, da sockaddr_any unvollständigen Typ hat (ich kann den Header nicht finden); aber als typecast funktioniert, ist das Problem gelöst :) –

0

Mit Laszlo Antwort, gibt es eine einfache Lösung für mein Problem. Das liegt nicht daran, dass die Definition der Struktur sockaddr_any in meinem Kontext nicht zugänglich ist (es gibt keine einfache Möglichkeit, auf das Feld addr zuzugreifen), dass der Zeiger nicht umgewandelt werden kann. Also, ich kann einfach tun:

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

Dann habe ich usable_pointer wie jede andere sockaddr Variable verwenden können.

Vielen Dank

+0

Gern geschehen. Das war auch meine erste Idee, wollte aber eine Typbesetzung vermeiden. – Laszlo