dounianluo0086 2016-10-24 07:32
浏览 138
已采纳

如何从C函数将字符串读取到Go中?

I'm trying to call a C function from Go with cgo to read an error message. The function produces a message of an unknown length less than 256 bytes.

Working example in C:

char message[ERROR_SIZE]; //256
last_error( message, sizeof(message) );         
printf( "message: %s
", message );

My attempt in Go (not working):

var ptr *C.char
C.last_error(ptr, ERROR_SIZE)
var message = C.GoString(ptr)
fmt.Printf("message: %s
", message)

When the go code is run, the message is empty. Does the go version need to preallocate space for the message? How to do this?


Update after comment by LPs to pass an array. This works, but seems a bit awkward:

var buf [ERROR_SIZE]byte
var ptr = (*C.char)(unsafe.Pointer(&buf[0]))
C.last_error(ptr, len(buf))
var message = C.GoString(ptr)
fmt.Printf("message: %s
", message)

Is there a simpler way?

  • 写回答

1条回答 默认 最新

  • douchun6221 2016-10-24 14:31
    关注

    In your first example you are passing a nil pointer, so there is no allocated memory for C.last_error to write the output to (and luckily, it appears to just do nothing).

    You need to allocate the memory somehow, and the most straightforward way to do that in Go is to use a slice, rather than create an array with a static size.

    buf := make([]byte, ERROR_SIZE)
    C.last_error((*C.char)(unsafe.Pointer(&buf[0])), len(buf))
    
    // While C.GoString will find the terminating null if it's there, 
    // there's no reason to copy the string in C, and allocate another slice.
    if i := bytes.IndexByte(buf, 0); i >= 0 {
        buf = buf[:i]
    }
    
    fmt.Printf("message: %s
    ", buf)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog