Golang中CGO回调函数传递C字符串指针的实现方法
Golang中CGO回调函数传递C字符串指针的实现方法
// 初始化 C 字符串
str := C.Cstring("foo")
// 调用带有回调函数 callback(void *) 和 str 的 C 函数
C.cfun(str, C.callback) // cfun(void *data)
// C.callback 调用 goCallback
callback(void * data){
// 此时可以获取到 str,但在 goCallback() 函数内部却不行。
goCallback(data);
}
可能的原因是什么?
2 回复
你必须在Go回调函数中调用C.GoString或C.GoStringN来转换为Go的string类型。引自cgo命令 - cmd/cgo - pkg.go.dev
// C string to Go string
func C.GoString(*C.char) string
// C data with explicit length to Go string
func C.GoStringN(*C.char, C.int) string
更多关于Golang中CGO回调函数传递C字符串指针的实现方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在CGO回调函数中传递C字符串指针时,需要确保Go回调函数接收正确的参数类型。问题在于Go回调函数没有正确声明接收C字符串指针的类型。以下是正确的实现方法:
package main
/*
#include <stdlib.h>
#include <string.h>
typedef void (*callback_t)(void*);
void cfun(void* data, callback_t cb) {
cb(data);
}
static void c_callback(void* data) {
// C端的回调函数
}
*/
import "C"
import (
"fmt"
"unsafe"
)
//export goCallback
func goCallback(data unsafe.Pointer) {
// 将C字符串指针转换为Go字符串
str := C.GoString((*C.char)(data))
fmt.Printf("Received string: %s\n", str)
}
func main() {
// 初始化C字符串
str := C.CString("foo")
defer C.free(unsafe.Pointer(str)) // 确保释放内存
// 调用C函数,传递字符串指针和回调函数
C.cfun(unsafe.Pointer(str), C.callback_t(C.c_callback))
}
需要创建C端的包装函数:
// 在C代码部分添加
static void c_callback(void* data) {
void goCallback(void*);
goCallback(data);
}
或者使用更直接的方式:
package main
/*
#include <stdlib.h>
typedef void (*callback_t)(char*);
void cfun(char* data, callback_t cb) {
cb(data);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
//export goCallback
func goCallback(data *C.char) {
str := C.GoString(data)
fmt.Printf("Received string: %s\n", str)
}
func main() {
str := C.CString("foo")
defer C.free(unsafe.Pointer(str))
// 直接传递Go回调函数给C
C.cfun(str, C.callback_t(C.goCallback))
}
关键点:
- Go回调函数需要使用
//export指令导出 - 参数类型需要正确匹配:
unsafe.Pointer或具体的C类型(如*C.char) - C字符串需要使用
C.CString创建,并用C.free释放 - 回调函数类型需要在C端正确定义
如果仍然无法在goCallback中获取字符串,检查C函数的回调签名是否与Go函数匹配,并确保内存管理正确。

