我有一个场景,其中C库以float array
作为参数,并且(在某个地方的某个地方)调用OCaml函数:
-------------
| a) OCaml | p : value (float array)
-------------
||
\/
---------
| b) C | p : double*
---------
||
\/
------------
| c) OCaml | p : value (float array)
------------
原则上,由于OCaml的智能内存布局,人们可以直接将value
作为double*
传递到C库中,而一切只是工作(TM)。也就是说,直到部分c)中发生了一些分配。
当GC决定清理次要堆时,double *指针可能变为无效。由于这只能发生在b)中的参数中,我想发信号通知GC“做你想做的任何事情,但在我告诉你之前不要移动这些块中的内容”。有没有办法使用OCaml API实现这一目标?
答案 0 :(得分:1)
一个bigarray将是解决这个问题的正确方法,但这意味着你不能只将double *
指针从C传递给OCaml,你必须跟踪代表bigarray的自定义块。 / p>
还有另外一种方法,虽然它不那么优雅且不那么健壮:你可以通过执行以下两项来确保float array
不会移动:
Gc.minor
)Gc.set
将max_overhead
设置为1000000)答案 1 :(得分:0)
您可以按照manual中的说明创建自定义功能块。但我建议你一个更好的解决方案。考虑使用Bigarrays。
答案 2 :(得分:0)
如果您希望GC跟踪您的本地值,您应该使用CAMLparam *声明,例如CAMLparam1(p)
而不是double *p
。
这将允许GC更新您的值指针并确保其安全。
您仍然可以通过double*
诀窍将p
复制到具有正确胁迫的double* p2
中,您只需要做两次:
所以你的代码看起来像那样:
value myfunction (value p_v)
{
CAMLparam1(p_v);
double *p = (double*) p_v;
/* actions over p */
callback(p_v);
p = (double*) p_v;
/* remainder of your code */
CAMLreturn (value_to_return);
}
有关良好的GC互动的更多信息,请阅读OCaml manual。