go - 对为什么这个 cgo 代码 panic 感到困惑

标签 go cgo

我想写一个使用golang调用c函数的demo,写了这个文件,发现会出现panic,不知道为什么。

首先是一个c头文件p.h:

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

二、一个c文件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));
    }

很简单,go代码一个output函数,go代码一个cc函数调用c_ccB,最后一个go代码文件是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
              }();
      }

go代码就是两个goroutime不断打印一些字符串,如果删除C.cc(cstr),它会正常工作,但是为什么C.cc会导致 panic ?它只是在 go 中调用 func c_ccB

这是 panic 信息:

      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

最佳答案

您在您的 C 代码中错过了 c_ccB 的声明。请将 extern char* c_ccB(char*); 添加到 p.c

而且,您忘记释放分配给 c_ccB 中的 CString 的内存。

关于go - 对为什么这个 cgo 代码 panic 感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37384246/

相关文章:

go - := and = in Go?有什么区别

go - Go语言的cgo如何编译Cuda源码?

MySQL UDF 返回 "Error Code: 1127. Can' t 在库中查找符号 'xx'”

go - 将 slice 解包到结构值

string - 在 Golang 中将字符串传递给准备好的语句

go - 如何在 golang 中使用 LDFLAGS 的相对路径

go - 如何在 cgo 导出函数中获取正确的参数名称?

戈朗 : cgo extern is not working

mongodb - 使用结构为 Controller 进行模型子类化

loops - 去审核-循环变量我被func文字捕获