将glib绑定到Crystal lang(GC问题)

时间:2016-02-09 23:22:41

标签: garbage-collection glib crystal-lang boehm-gc

我正在尝试将一些函数从glib绑定到Crystal中。我已经做到了这一点并且有效:

@[Link("glib-2.0")]
lib LibG
  fun g_utf8_strup(str : UInt8*, len : UInt32) : UInt8*
  fun g_utf8_strdown(str : UInt8*, len : UInt32) : UInt8*
end

然而,它引入了内存泄漏:使用g_ *函数创建的对象永远不会被垃圾回收。

是否有可能让格里布在水晶中与Boehm GC一起发挥出色?受PCRE的启发,我试过这个:

@[Link("glib-2.0")]
lib LibG
  # These 2 functions work perfectly
  fun g_utf8_strup(str : UInt8*, len : UInt32) : UInt8*
  fun g_utf8_strdown(str : UInt8*, len : UInt32) : UInt8*

  alias Malloc = LibC::SizeT -> Void*
  alias Free = Void* ->
  $g_malloc : Malloc
  $g_free : Free
end

# At this point happens segmentation fault
LibG.g_malloc = ->GC.malloc(LibC::SizeT)
LibG.g_free = ->GC.free(Void*)

希望覆盖/重新定义g_mallocg_free函数。 但它没有成功:它失败了分段错误。

如何使用GC制作滑稽的想法? 我发现了某种相关问题,但它对我没有帮助:Garbage collection with glib?

感谢advence。

1 个答案:

答案 0 :(得分:1)

我建议将gobject-introspection用于此目的。它为每个库提供.GIR文件,该文件是一个大型XML文件,用于描述库中每个函数,类和方法的API,以及如何为每个输入和输出参数处理内存。您可以使用它为GLib等库动态生成绑定。

它还提供了一个扩展的单元测试库,您可以使用它来检查绑定是否正常工作。

至于内存管理,似乎要求覆盖g_mallocg_free时遇到麻烦。它在JavaScript的gobject-introspection绑定中所做的等效方法是始终确保JS环境拥有内存。例如,对于从C函数返回的字符串;如果返回字符串的所有权被赋予调用者,则从返回的字符串(复制字符串)创建JS字符串,并释放返回的字符串。如果库保留了返回字符串的所有权,则会创建JS字符串,并且不会释放返回的字符串。在这两种情况下,使用的唯一内存都归JS环境所有,并受JS的垃圾收集器的限制。

GLib对象是另一个故事,因为它们是引用计数的,因此JS包装器对象可以简单地保存对它们的引用;当JS对象是GC时,它会释放它的引用,如果没有其他JS对象保留它,C对象也会被销毁。