代码之家  ›  专栏  ›  技术社区  ›  Hobbestigrou

从go调用C函数

  •  2
  • Hobbestigrou  · 技术社区  · 8 年前

    我刚开始学习围棋语言,我开始非常喜欢围棋 语言 要读取阴影文件,我的代码是:

    // #cgo CFLAGS: -D_POSIX_SOURCE=1
    // #include <stdlib.h>
    // #include <shadow.h>
    // size_t size_of_shadow() { return sizeof(struct spwd); }
    import "C"
    import "unsafe"
    import "fmt"
    
    type Shadow struct {
        Name   string
        Passwd string
    }
    
    func Getspnam(name string) (*Shadow, error) {
        cname := C.CString(name)
        cspwd := (*C.struct_passwd)(C.malloc(C.size_of_shadow()))
        buf := (*C.char)(C.malloc(1024))
        _, err := C.getspnam_r(cname, cspwd, 1024, &cpwd)
    
        if unsafe.Pointer(cspwd) == unsafe.Pointer(uintptr(0)) {
            C.free(unsafe.Pointer(cname))
    
            if err == nil {
                err = fmt.Errorf("User %s not found", name)
            }
    
            return nil, err
        }
    
        s := Shadow{
            Name: C.GoString(cspwd.sp_namp),
            Passwd: C.GoString(cspwd.sp_pwdp),
        }
    
        C.free(unsafe.Pointer(cname))
        C.free(unsafe.Pointer(cspwd))
        C.free(unsafe.Pointer(buf))
    
        return &s, nil
    }
    

    灵感来自这个小项目和 课程:

    https://github.com/LTD-Beget/passwd http://linux.die.net/man/3/getspnam

    我使用的是debian拉伸go 1.6版本,安装了包管理器。 尝试编译文件时出错:

    could not determine kind of name for C.getspnam_r
    

    但当我打开头文件阴影时。h、 然而,该功能在 文件。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Hobbestigrou    8 年前

    我改正了我的错误。错误是使用了标志some是不必要的,并且在结构名称上键入了错误:

    // #include <stdlib.h>
    // #include <shadow.h>
    // size_t size_of_shadow() { return sizeof(struct spwd); }
    import "C"
    
    import "C"
    import "unsafe"
    import "fmt"
    
    type Shadow struct {
        Name   string
        Passwd string
    }
    
    func Getspnam(name string) (*Shadow, error) {
        cname := C.CString(name)
        defer C.free(unsafe.Pointer(cname))
    
        cspwd := (*C.struct_spwd)(C.malloc(C.size_of_shadow()))
        defer C.free(unsafe.Pointer(cspwd))
    
        buf := (*C.char)(C.malloc(1024))
        defer C.free(unsafe.Pointer(buf))
    
        _, err := C.getspnam_r(cname, cspwd, buf, 1024, &cspwd)
    
        if unsafe.Pointer(cspwd) == unsafe.Pointer(uintptr(0)) {
            if err == nil {
                err = fmt.Errorf("User %s not found", name)
            }
    
            return nil, err
        }
    
        s := Shadow{
            Name:   C.GoString(cspwd.sp_namp),
            Passwd: C.GoString(cspwd.sp_pwdp),
        }
    
        return &s, nil
    }
    

    代码的新版本。