如何在go中将字节转换为struct(c struct)?

时间:2017-07-26 06:03:16

标签: c unix go

var request = URLRequest(url: URL(string: "http://app123.freeiz.com/Apis/samples/api4.php")!)
request.httpMethod = "POST"
var postString =  ""
postString.append("function=value") // replace 'function' with your paramname and 'value' with your value'
request.httpBody = postString.data(using: .utf8)

let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {
            // check for fundamental networking error
            print("error=\(String(describing: error))")
            return
        }

        if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
            // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(String(describing: response))")
        }

        let responseString = String(data: data, encoding: .utf8)

        if let unWrappedResponseString = responseString{

            print(unWrappedResponseString)
        }

    }
    task.resume()

我试图将package main /* #define _GNU_SOURCE 1 #include <stdio.h> #include <stdlib.h> #include <utmpx.h> #include <fcntl.h> #include <unistd.h> char *path_utmpx = _PATH_UTMPX; typedef struct utmpx utmpx; */ import "C" import ( "fmt" "io/ioutil" ) type Record C.utmpx func main() { path := C.GoString(C.path_utmpx) content, err := ioutil.ReadFile(path) handleError(err) var records []Record // now we have the bytes(content), the struct(Record/C.utmpx) // how can I cast bytes to struct ? } func handleError(err error) { if err != nil { panic("bad") } } 读入content 我问了一些相关的问题。

Cannot access c variables in cgo

Can not read utmpx file in go

我已经阅读了一些文章和帖子,但仍然无法找到一种方法来做到这一点。

1 个答案:

答案 0 :(得分:2)

我认为你这是错误的做法。如果您想使用C库,可以使用C库来读取文件。

不要纯粹使用cgo来定义结构,你应该自己创建这些定义。然后,您可以编写适当的marshal / unmarshal代码以从原始字节读取。

快速Google表明有人已经完成了将相关C库的外观转换为Go所需的工作。请参阅utmp repository

如何使用它的一个简短例子是:

package main

import (
    "bytes"
    "fmt"
    "log"

    "github.com/ericlagergren/go-gnulib/utmp"
)

func handleError(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

func byteToStr(b []byte) string {
    i := bytes.IndexByte(b, 0)
    if i == -1 {
        i = len(b)
    }
    return string(b[:i])
}

func main() {
    list, err := utmp.ReadUtmp(utmp.UtmpxFile, 0)
    handleError(err)
    for _, u := range list {
        fmt.Println(byteToStr(u.User[:]))
    }
} 

您可以查看utmp包的GoDoc以获取更多信息。