Golang中如何将void指针传递给C函数

Golang中如何将void指针传递给C函数 我正在编写一个cgo包装器。 我需要调用的C函数如下所示:

int my_c_func (void *obj, const char *name, int64_t val, int search_flags);

我在Go中的包装函数如下所示:

func (ctx *Context) AvOptionSetInt(key string, value int64, flags int) int {
	Ckey := C.CString(key)
	defer C.free(unsafe.Pointer(Ckey))

	return (int)(C.my_c_func((*C.void)((unsafe.Pointer)(ctx.priv_data)), Ckey, (C.int64_t)(value), C.int(flags)))
}

我遇到了以下错误。 cannot use cgo0 (type *_Ctype_void) as type unsafe.Pointer in argument to Cfunc_my_c_func

我理解Go语言中没有void *,但这只是类型转换为一个C数据结构。你能帮我解决这个问题吗?


更多关于Golang中如何将void指针传递给C函数的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

谢谢。

更多关于Golang中如何将void指针传递给C函数的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


CGO 文档 指出:

C 语言中的 void* 类型由 Go 的 unsafe.Pointer 表示。

因此,移除 (*C.void)

在cgo中处理void指针时,可以直接使用unsafe.Pointer类型,无需转换为*C.void。以下是修正后的代码:

func (ctx *Context) AvOptionSetInt(key string, value int64, flags int) int {
    Ckey := C.CString(key)
    defer C.free(unsafe.Pointer(Ckey))

    return int(C.my_c_func(
        unsafe.Pointer(ctx.priv_data),
        Ckey,
        C.int64_t(value),
        C.int(flags),
    ))
}

如果ctx.priv_data已经是unsafe.Pointer类型,可以直接传递。如果它是其他类型的指针,比如*C.some_type,cgo会自动处理转换。

如果需要显式类型转换,可以这样写:

func (ctx *Context) AvOptionSetInt(key string, value int64, flags int) int {
    Ckey := C.CString(key)
    defer C.free(unsafe.Pointer(Ckey))

    // 如果ctx.priv_data是具体类型
    return int(C.my_c_func(
        unsafe.Pointer(ctx.priv_data),  // 直接使用unsafe.Pointer
        Ckey,
        C.int64_t(value),
        C.int(flags),
    ))
}

对于更复杂的场景,比如需要处理不同类型的void指针参数:

// 处理多种指针类型的示例
func CallCFunctionWithVoidPtr() {
    var goObj interface{}
    var cPtr unsafe.Pointer
    
    // 从Go指针获取unsafe.Pointer
    if ptr, ok := goObj.(*SomeStruct); ok {
        cPtr = unsafe.Pointer(ptr)
    }
    
    // 调用C函数
    result := C.my_c_func(
        cPtr,           // void *参数
        nil,            // const char *参数
        C.int64_t(0),   // int64_t参数
        C.int(0),       // int参数
    )
    
    _ = result
}

关键点是:cgo中unsafe.Pointer直接对应C的void*类型,无需额外转换。

回到顶部