2016-07-21 3 views
1

Я пытаюсь отправить некоторые данные из программы C в Голанг. Данные представляют собой исходную структуру C. Я пытаюсь развязать его в Голанге.Каков наилучший способ совместного использования определения структуры в C и Golang?

Образец так:

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

Способ заключается в переписать эту C-структуру для Golang структуры. Скажи:

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

А затем преобразовать сырой поток байтов данных к нему с помощью encoding/binary. Но используя этот метод, я должен поддерживать две разные взаимосвязанные структуры.

Другой метод заключается в использовании Cgo, просто импортируйте файл заголовка языка C (.h), содержащий эту структуру, и используйте C.A и небезопасную точку для преобразования необработанных данных в структуру C.A. Но это как-то багги, и я разбился, чтобы преобразовать массив C char в строку Golang.

Каков ваш выбор? Любое предложение?

+0

Это очень плохой подход. Определите формат последовательных данных и используйте правильную сериализацию с битами/маскированием с обеих сторон. Существует достаточно вопросов и ответов об этом, которые можно найти простым поиском. – Olaf

+0

Спасибо @Olaf, при изменении полей инкапсуляции изменилась оболочка обоих кодов? Существует ли подход к «совместному определению» в одном месте? – LiLinZhe

+0

@LiLinZhe, вы можете использовать протокол serializtion со схемой, например, «Буферы протоколов» или FlatBuffers – JimB

ответ

2

один способ использования ОЦП: Вы можете получить доступ к любому поля C структуры, используя var s *C.struct_tagA = &C.N или просто используя s := &C.N как этот рабочий пример кода:

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 

} 

выход:

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

вы можете использовать s.a , s.b и s.c непосредственно в Голанге. вам не нужно копировать все это.