在 C 和 Golang 中共享结构定义的最佳方式是什么

LiL*_*Zhe 6 interop go

我正在尝试将一些数据从 C 程序发送到 Golang。数据由原始 C 结构表示。我正在尝试在 Golang 中对其进行解组。

像这样的示例:

typedef struct tagA {
    int64_t a;
    int64_t b;
    char  c[1024];
}A;
Run Code Online (Sandbox Code Playgroud)

一种方法是将这个 C 结构体重写为 Golang 结构体。说:

type A struct{
    a int64
    b int64
    c [1024]byte
}
Run Code Online (Sandbox Code Playgroud)

然后使用encoding/binary. 但是使用这种方法,我应该维护两个不同的相互关联的结构。

另一种方法是使用Cgo,只需导入.h包含此结构的 C 语言头文件(),并使用C.A不安全点将原始数据转换为结构 CA 但它在某种程度上有问题,我在将 C 字符数组转换为 Golang 字符串时崩溃了。

你有什么选择?有什么建议吗?

小智 8

使用 cgo 的一种方法:您可以访问 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

}
Run Code Online (Sandbox Code Playgroud)

输出:

len(s.c): 1024
len:4 "test" 
120
Run Code Online (Sandbox Code Playgroud)

您可以直接在 Golang 中使用s.a,s.bs.c。您无需复制所有内容。