2017-07-26 22 views
0
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转换为Record 我已经提出了一些相关问题。如何投入字节结构(C结构)在去?

Cannot access c variables in cgo

Can not read utmpx file in go

我看过一些文章和帖子,但仍然无法想出一个办法做到这一点。

回答

2

我想你会错误地回答这个问题。如果你想使用C库,你可以使用C库来读取文件。

不要单纯使用cgo来定义结构,你应该在Go中创建它们。然后,您可以编写适当的编组/解组码来从原始字节读取。

快速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[:])) 
    } 
} 

您可以查看GoDocutmp包以获取更多信息。

+0

我知道这个回购,我已经读过它。我只想尝试一下。感谢您的回答。我得到了'undefined:utmp.ReadUtmp','undefined:utmp.UtmpxFile'。 –

+0

我想等着看有没有其他答案。 –

+1

GZ薛,你运行了'go get github.com/ericlagergren/go-gnulib/utmp'来安装utmp库吗? – Mark