2016-05-23 5 views
0

Ich möchte eine Demo über die Verwendung von Golang Call C-Funktion schreiben, und ich schreibe diese Dateien und fand es wird Panik bekommen und ich weiß nicht warum.Verwirrt über, warum diese cgo Code Panik

Zuerst ac Header-Datei p.h:

void output(char* str, int s); 
    void cc(char *str); 

Zweitens ac Datei p.c:

#include<stdio.h> 
    #include<stdlib.h> 
    #include<unistd.h> 

    void output(char* str, int s) { 
      fflush(stdout); 
      sleep(s); 
      printf("%s", str); 
    } 

    void cc(char *str) { 
      printf("%s", c_ccB(str)); 
    } 

Es ist ganz einfach, eine output Funktion für Go-Code und ein cc Funktionsaufruf c_ccB in go Code , die letzte Go-Code-Datei ist p.go:

 package main 

    /* 
    #include<stdlib.h> 
    #include "p.h" 
    */ 
    import "C" 
    import "unsafe" 
    import "fmt" 

    //export c_ccB 
    func c_ccB(cs *C.char) *C.char { 
      gs := C.GoString(cs) 
      return C.CString(gs + "wwww") 
    } 

    func main() { 
      ch := make(chan int) 
      task("A", ch, 5) 
      task("B", ch, 1) 
      fmt.Printf("begin\n") 
      <-ch 
    } 

    func task(name string, ch chan int, s int) { 
      go func() { 
        i:= 1 
        for { 
           str := ":" + name 
           cstr := C.CString(str) 
           C.output(cstr, C.int(s)) 
           C.cc(cstr) 
           C.free(unsafe.Pointer(cstr)) 
           i++ 
        } 
        ch <- 1 
       }(); 
     } 

Der go-Code ist nur zwei goroutime halten Sie einige Zeichenfolgen, wenn löschen C.cc(cstr), wird es gut funktionieren, aber warum C.cc wird Panik verursachen? Rufen Sie einfach func c_ccB in go an. Hier

ist die Panik Nachricht:

 begin 
     :B:Bwwww:B:Bwwww:B:Bwwww:B:Bwwwwfatal error: unexpected signal  during runtime execution 
     [signal 0xb code=0x1 addr=0x900008e0 pc=0x7ff5973f8c80] 

     runtime stack: 
     runtime.throw(0x5438a0, 0x2a) 
      /usr/local/go/src/runtime/panic.go:547 +0x90 
     runtime.sigpanic() 
      /usr/local/go/src/runtime/sigpanic_unix.go:12 +0x5a 

     goroutine 5 [syscall, locked to thread]: 
     runtime.cgocall(0x4b1b20, 0xc82002bf20, 0x0) 
     /usr/local/go/src/runtime/cgocall.go:123 +0x11b      fp=0xc82002bee8 sp=0xc82002beb8 
     main._Cfunc_cc(0x7ff5900008c0) 
     _/home/suwey/code/go/src/_obj/_cgo_gotypes.go:62 +0x36 fp=0xc82002bf20 sp=0xc82002bee8 
     main.task.func1(0x51bf48, 0x1, 0x5, 0xc820062060) 
     /home/suwey/code/go/src/p.go:32 +0xae fp=0xc82002bfa0 sp=0xc82002bf20 
     runtime.goexit() 
     /usr/local/go/src/runtime/asm_amd64.s:1998 +0x1 fp=0xc82002bfa8 sp=0xc82002bfa0 
     created by main.task 
     /home/suwey/code/go/src/p.go:37 +0x53 

     goroutine 1 [chan receive]: 
     main.main() 
     /home/suwey/code/go/src/p.go:22 +0xda 

     goroutine 17 [syscall, locked to thread]: 
     runtime.goexit() 
     /usr/local/go/src/runtime/asm_amd64.s:1998 +0x1 

     goroutine 6 [syscall, locked to thread]: 
     main._Cfunc_output(0x1de38b0, 0x1) 
     _/home/suwey/code/go/src/_obj/_cgo_gotypes.go:74 +0x3a 
     main.task.func1(0x51bfd0, 0x1, 0x1, 0xc820062060) 
     /home/suwey/code/go/src/p.go:31 +0xa0 
     created by main.task 
     /home/suwey/code/go/src/p.go:37 +0x53 
+0

was die Fehlermeldung in Panik? –

+0

hinzugefügt die Fehlermeldung – suwey

+0

Neben den C-Compiler-Warnungen, weil Sie "_cgo_export.h" und den Speicherverlust nicht enthalten, weil Sie die CString von c_ccB nicht befreien, sehe ich keinen Grund zu segfault. Welche Version von Go verwendest du? – JimB

Antwort

0

Sie die Deklaration von c_ccB in Ihrem C-Code verpasst. Fügen Sie bitte extern char* c_ccB(char*); zu Ihnen p.c hinzu.

Und Sie vergessen, den Speicher für CString in c_ccB freizugeben.

+0

keine Notwendigkeit, 'c_ccB' erneut zu deklarieren, und ja, ich habe den Speicher nicht freigegeben, da' C.free' func 'c_ccB' einen Nullwert zurückgeben kann. – suwey

+0

'wieder'? wo kann dein 'p.c' die Deklaration von' c_ccB' bekommen? –

+0

Ich weiß nicht, wie gehen Sie damit um, und ich habe eine Warnmeldung mit GCC 5.3.1, aber keine Warnmeldung mit GCC 4.4.6. Und es ist nur eine Warnmeldung. – suwey