Golang中如何向C函数传递NULL参数

Golang中如何向C函数传递NULL参数 我是Go语言的新手,正在编写一个C-GO绑定。

C函数接受一个参数,类型是const char *。如果在C中为该参数传递NULL,这可以正常工作。

现在在我的GO实现中,我需要在C调用中传递NULL。

func AvformatMyfunc(ctx **Context, o *OutputFormat, fo, fi string) int {
	Cformat_name := C.CString(fo)
	defer C.free(unsafe.Pointer(Cformat_name))

	Cfilename := C.CString(fi)
	defer C.free(unsafe.Pointer(Cfilename))

	return int(C.myfunc((**C.struct_AVFormatContext)(unsafe.Pointer(ctx)), (*C.struct_AVOutputFormat)(o),  Cformat_name, Cfilename))
}

这是我在主包中调用它的方式。

if AvformatMyfunc(&ofmt_ctx, nil, "", os.Args[2]) != 0 {
		fmt.Printf("Unable to open output file %s\n", os.Args[2]);
		os.Exit(1);
	}

我上面粘贴的代码传递了空字符串,导致我的C代码失败。它期望传递NULL或某个有效的字符串作为参数。请问有什么建议吗? 提前感谢。


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

3 回复

不。只需要传递 NULL,而不是空字符串。

我通过使用 *(*C.char)(nil) 解决了这个问题。

*(*C.char)(nil)

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


Go 语言中没有空字符串的概念。如果你可以接受空字符串始终对应 C 语言中的空指针,可以这样做:

func AvformatMyfunc(ctx **Context, o *OutputFormat, fo, fi string) int {
	var Cformat_name *C.char
	if fo != "" {
		Cformat_name = C.CString(fo)
		defer C.free(unsafe.Pointer(Cformat_name))
	}

	var Cfilename *C.char
        if fi != "" {
                Cfilename = C.CString(fi)
        	defer C.free(unsafe.Pointer(Cfilename))
        }
	return int(C.myfunc((**C.struct_AVFormatContext)(unsafe.Pointer(ctx)), (*C.struct_AVOutputFormat)(o),  Cformat_name, Cfilename))
}

在Go中向C函数传递NULL参数,可以使用unsafe.Pointer和类型转换来实现。对于const char*参数,可以通过传递nil或零值指针来模拟C的NULL。

以下是修改后的示例代码:

func AvformatMyfunc(ctx **Context, o *OutputFormat, fo, fi string) int {
    var Cformat_name *C.char
    if fo != "" {
        Cformat_name = C.CString(fo)
        defer C.free(unsafe.Pointer(Cformat_name))
    }

    var Cfilename *C.char
    if fi != "" {
        Cfilename = C.CString(fi)
        defer C.free(unsafe.Pointer(Cfilename))
    }

    return int(C.myfunc(
        (**C.struct_AVFormatContext)(unsafe.Pointer(ctx)),
        (*C.struct_AVOutputFormat)(o),
        Cformat_name,  // 空字符串时这里会是nil
        Cfilename,     // 空字符串时这里会是nil
    ))
}

或者更简洁的版本:

func AvformatMyfunc(ctx **Context, o *OutputFormat, fo, fi string) int {
    var Cformat_name *C.char
    if fo != "" {
        Cformat_name = C.CString(fo)
        defer C.free(unsafe.Pointer(Cformat_name))
    }

    var Cfilename *C.char
    if fi != "" {
        Cfilename = C.CString(fi)
        defer C.free(unsafe.Pointer(Cfilename))
    }

    return int(C.myfunc(
        (**C.struct_AVFormatContext)(unsafe.Pointer(ctx)),
        (*C.struct_AVOutputFormat)(o),
        Cformat_name,
        Cfilename,
    ))
}

调用方式保持不变:

if AvformatMyfunc(&ofmt_ctx, nil, "", os.Args[2]) != 0 {
    fmt.Printf("Unable to open output file %s\n", os.Args[2])
    os.Exit(1)
}

fo参数为空字符串时,Cformat_name保持为nil,这会被C代码识别为NULL指针。同样地,fi参数为空字符串时,Cfilename也会是nil。这样就能正确地向C函数传递NULL参数了。

回到顶部