gpt4 book ai didi

go - runtime.SetFinalizer:无法确定C.Char的名称种类

转载 作者:行者123 更新时间:2023-12-01 22:12:54 24 4
gpt4 key购买 nike

请考虑以下示例代码:

package main

/*
#include <stdio.h>
#include <stdlib.h>
*/
import "C"


import (
"fmt"
"runtime"
"unsafe"
)

func main() {
// Convert Go string to C string using C.CString
cString := C.CString("Wold!")
fmt.Printf("C.CString type: %T\n", cString)
//C.free(unsafe.Pointer(cString)) // <-- this works, but I don't want to free it manually..

runtime.SetFinalizer(&cString, func(t *C.Char) {
C.free(unsafe.Pointer(t))
})
}

我正在尝试使用cGo,并尝试释放 cString。当我尝试使用 runtime.SetFinalizer释放变量cString时遇到:
$ go build a.go 
# command-line-arguments
./a.go:22:41: could not determine kind of name for C.Char

请指出正确的方向。谢谢!

最佳答案

当cgo系统将包装程序转换成Go编译器可以理解的东西时,出于各种目的,它必须将每个C类型转换为Go类型。事实证明,这不适用于您的情况(这是您看到的错误)。
这实际上是可以的,因为您的代码最初不会像您想要的那样工作。当Go的垃圾回收器准备释放占用Go内存的Go对象时,运行时终结器将运行,但是C.Cstring返回的指针不是Go内存。特别要注意the cgo documentation的以下引号:

// Go string to C string
// The C string is allocated in the C heap using malloc.
// It is the caller's responsibility to arrange for it to be
// freed, such as by calling C.free (be sure to include stdlib.h
// if C.free is needed).
func C.CString(string) *C.char

因为返回的字符串在“C堆”上,所以它永远不会被Go垃圾收集器终结。如果您的代码已编译,那将是无操作的。
如果您的Go对象的生存期与C对象的生存期相似,则可以使用该对象。这是一个虚构的(但可行的)示例:
package main

/*
#include <stdio.h>
#include <stdlib.h>
*/
import "C"

import (
"fmt"
"runtime"
"time"
"unsafe"
)

type S struct {
Foo int
ToFree unsafe.Pointer
}

func main() {
doit()
runtime.GC()
time.Sleep(10 * time.Millisecond) // ugly hack
}

func doit() {
cString := C.CString("Wold!")
fmt.Printf("C.CString type: %T\n", cString)
x := &S{Foo: 1, ToFree: unsafe.Pointer(cString)}
runtime.SetFinalizer(x, func(t *S) {
fmt.Println("freeing C string")
C.free(t.ToFree)
})
}
当为 x分配的对象超出范围时,它就有资格使用GC。实际的GC可能永远不会发生,因此我在 runtime.GC()中用 main强制了一个。这触发了终结器:
$ ./cfree_example
C.CString type: *main._Ctype_char
freeing C string
之所以会出现“丑陋的骇客”,是因为如果在完成终结器调用完成 main消息的写入之前 freeing C string返回,它将丢失。在实际程序中,您不需要此。

关于go - runtime.SetFinalizer:无法确定C.Char的名称种类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62482446/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com