0

我正在将这个 C API 移植到https://github.com/shammash/vde3中,该库有自己的使用 libevent 的事件循环,我正在使用 CGO。

该库需要以这种方式组成的完整 vde_event_handler

{event_add = 0x7fffe4de0db0, event_del = 0xc2000123a8, timeout_add = 0xc200000090, timeout_del = 0xc200010400}

具有一系列指向函数的指针的结构

在执行过程中,该字段设置为 NULL,我不明白为什么,我认为可能是 go 垃圾收集器(出于某种原因)找到参考 dandling 并删除它们,但这不应该是这种情况

这是被指控的功能https://github.com/kurojishi/govde3/blob/master/govde.go#L23

func createNewEventHandler() *C.vde_event_handler {
    var libevent_eh C.vde_event_handler
    C.event_base_new()
    return &libevent_eh
}

这是一个gdb日志

(gdb) p *libevenet_eh
No symbol "libevenet_eh" in current context.
(gdb) p *libevent_eh
$1 = {event_add = 0x7fffe0000900, event_del = 0x30302e3028, timeout_add = 0x65736c6166, timeout_del = 0x0}
(gdb) info locals
libevent_eh = 0xc200000098
err = {__methods = 0x0, __object = 0x0}
(gdb) n

Breakpoint 1, govde.createNewEventHandler ()
at /home/kurojishi/golang/src/github.com/kurojishi/govde3/govde.go:23
23  func createNewEventHandler() C.vde_event_handler {
(gdb) info locals
$ret11 = {event_add = 0x7fffe4de0db0, event_del = 0xc2000123a8, timeout_add = 0xc200000090, timeout_del = 0xc200010400}
(gdb) n

Breakpoint 2, govde.createNewEventHandler ()
at /home/kurojishi/golang/src/github.com/kurojishi/govde3/govde.go:24
24      var libevent_eh C.vde_event_handler
(gdb) info locals
libevent_eh = {event_add = 0x0, event_del = 0x3, timeout_add = 0x7fffe4de0f8f, timeout_del = 0x7fffe4de0f8f}
$ret11 = {event_add = 0x0, event_del = 0x0, timeout_add = 0x0, timeout_del = 0x0}
4

1 回答 1

3

您在 Go 中的 createNewEventHandler 中分配一个新的事件处理程序,将它传递给 VdeContext.Init 中的 C 代码,然后删除指针。效果是在 VdeContext.Init 返回后的某个时间,Go 垃圾收集器将收集事件处理程序结构,即使 C 代码仍然有指向它的指针。代码将保留一个指向内存的指针,该指针会发生不可预测的变化。

当你在 Go 中分配内存并将指针传递给 C 时,只要 C 代码需要引用它,就必须在 Go 中保持指针处于活动状态。

于 2014-04-10T15:57:31.073 回答