golang cgo : libevent handler values are set to null during execution

标签 go libevent cgo

我正致力于在 go 中移植此 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 垃圾收集器(出于某种原因)找到了引用并删除了它们,但事实并非如此

这是有罪的功能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}

最佳答案

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

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

关于golang cgo : libevent handler values are set to null during execution,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22988184/

相关文章:

arrays - 如何从 C 函数返回 C 结构数组?

json - 如何保护服务免受 gzip 炸弹的攻击?

处理大量 http 请求时,java.nio 与 libevent 应该选择什么?

go - 如何正确重新安装 Go 项目

c++ - 如何将 libusb 与 libevent 一起使用?

c - libevent 在 ubuntu 服务器 14.04 上的链接问题

sqlite - 如何使用 sqlite3.h 和 cgo 打开一个新的 sqlite3 数据库?

go - 如何将 *_Ctype_char 转换为 *_Ctype_uchar

go - 从 Go 代码构建 Docker 镜像

go - 在 SDL Go 程序中复制纹理时出现运行时 panic