2016-08-05 10 views
2

私は言語を学ぶことに全く新しいので、私はこの 言語の偉大な恋人になり始めました。 私はすぐに良いゴーファーになることを願っています。現在、私はshadowファイルを読み取るためにC関数 を呼び出そう、私のコードは次のとおりです。goからのCの関数を呼び出す

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

:この小さなプロジェクトと 当然の機能のドキュメントに触発さ

// #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 
} 

私はdebian stretch上にあり、パッケージマネージャーと共にインストールされた1.6バージョンになります。 私は私のファイルをコンパイルしようと、エラーました:

could not determine kind of name for C.getspnam_r 

をしかし、私はヘッダファイルshadow.hを開くと、機能が ファイルにただし存在しています。

+1

なぜあなたは '-D_POSIX_SOURCE = 1'を持っていますか? 'getspnam_r'関数はPOSIXではないので、マクロが干渉していると思います。 – JimB

+0

このフラグがないと別のエラーが表示されるので、https://friendpaste.com/2EFrPk78Ghx96kE4CW0V2Z – Hobbestigrou

+1

を参照してください。 'C.struct_passwd'の代わりに' C.struct_spwd'を使用してください。コンパイラはそこから残りの問題を指摘できるはずです。早く帰ってきたときにメモリを解放していないので、あなたの呼び出しを 'free'に延期するべきです。 – JimB

答えて

0

私の間違いを修正しました。エラーはフラグのいくつかが不要で、構造体の名前にタイプミスがありました。

// #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 
} 

新しいバージョンのコードです。

関連する問題