2016-07-21 11 views
1

zu teilen Ich versuche, einige Daten von C-Programm nach Golang zu senden. Die Daten werden durch rohe C-Struktur dargestellt. Ich versuche es in Golang zu entlarven.Was ist der beste Weg, Strukturdefinition in C und Golang

Eine Probe wie folgt aus:

typedef struct tagA { 
    int64_t a; 
    int64_t b; 
    char c[1024]; 
}A; 

Ein Verfahren ist es, dieses C struct Golang struct neu zu schreiben. Sprich:

type A struct{ 
    a int64 
    b int64 
    c [1024]byte 
} 

Und dann Rohdaten Byte-Strom umwandeln, um es encoding/binary verwenden. Aber mit dieser Methode sollte ich zwei verschiedene zusammenhängende Strukturen pflegen.

Ein andere Methode ist Cgo zu bedienen, einfach die Datei C Sprache Kopf importieren (.h) enthält diese Struktur, und verwenden Sie C.A und unsicheren Punkt Rohdaten zu konvertieren C.A. auf struct Aber es ist irgendwie fehlerhaft, und ich bin abgestürzt, um C Char Array in Golang String zu konvertieren.

Was ist Ihre Wahl? Irgendein Vorschlag?

+0

Das ist ein sehr schlechter Ansatz. Definieren Sie ein serielles Datenformat und verwenden Sie die richtige Serialisierung mit Bitshift/Maskierung auf beiden Seiten. Es gibt genügend Fragen und Antworten zu diesem Thema durch eine einfache Suche gefunden werden. – Olaf

+0

Dank @Olaf, beim Ändern der Kapselung Felder, beide Seiten Code Shell geändert werden? Gibt es einen Ansatz zur "Freigabe" Definition an einem Ort? – LiLinZhe

+0

@LiLinZhe, Sie können ein Serialization-Protokoll mit einem Schema verwenden, wie "Protocol Buffers" oder FlatBuffers – JimB

Antwort

2

eine Möglichkeit, mit CGO: Sie alle Felder von C-Struktur zugreifen kann, var s *C.struct_tagA = &C.N verwenden oder einfach s := &C.N wie dieser Arbeitsbeispielcode verwenden:

package main 

/* 
#include <string.h> 
#include <stdint.h> 
typedef struct tagA { 
    int64_t a; 
    int64_t b; 
    char c[1024]; 
}A; 

A N={12,22,"test"}; 
*/ 
import "C" 

import "fmt" 

type A struct { 
    a int64 
    b int64 
    c [1024]byte 
} 

func main() { 
    s := &C.N // var s *C.struct_tagA = &C.N 

    t := A{a: int64(s.a), b: int64(s.b)} 
    length := 0 
    for i, v := range s.c { 
     t.c[i] = byte(v) 
     if v == 0 { 
      length = i 
      break 
     } 
    } 

    fmt.Println("len(s.c):", len(s.c)) // 1024 
    str := string(t.c[0:length])  
    fmt.Printf("len:%d %q \n", len(str), str) // len:4 "test" 

    s.a *= 10 
    fmt.Println(s.a) // 120 

} 

Ausgang:

len(s.c): 1024 
len:4 "test" 
120 

Sie s.a verwenden , s.b und s.c direkt in Golang. Sie müssen nicht alles kopieren.

Verwandte Themen