erlang c节点传递二进制对象

时间:2014-11-18 15:54:14

标签: erlang libxl cnode

我正在关注Erlang C Nodes教程,并试图为libXl C库进行包装调用。 在我的C节点中,创建一个BookHandle并将其作为一个消息调用的响应传递。

BookHandle book = xlCreateBook();
resp = erl_format("{ok, ~w}", erl_mk_binary(book, sizeof book));
erl_send(fd, fromp, resp);

我的问题是我可以使用该响应将另一条消息发送到具有该同一对象的C节点吗? 例如发送

{any, 'c1@CST1'} ! {self(), {step2,Result}}, 

并在C节点中使用类似下面的代码来获取传递的BookHandle

if (strncmp(ERL_ATOM_PTR(fnp), "step2", 3) == 0) {
    BookHandle book = (BookHandle)ERL_BIN_PTR(argp);
    xlBookLoad(book, "example.xls");
}

这样的事情是可能的,或者为特定函数创建一个包装器,每当我向C节点发送消息时都需要创建BookHandle。

对不起,如果这没有任何意义,我是新手。

1 个答案:

答案 0 :(得分:0)

xlCreateBook()返回一个指针(BookHandle实际上是指向C ++对象Book的指针)。因此,您的代码将此指针序列化为Erlang二进制文件(可能长度为4或8个字节,具体取决于您的体系结构),并在从Erlang节点传回时对其进行反序列化。

这基本上有效

但是,它有以下两个缺点:

  • Erlang节点可以技术上传递任何指向C节点的指针,甚至是指向不指向真实Book结构的指针。这可能会导致崩溃或更糟糕的数据损坏。
  • 指针可能会丢失(通常是处理书籍的Erlang进程死亡),这会在C节点中产生内存泄漏(因为永远不会释放Book)。

出于这个原因,最好使用无状态API设计,尽管最终可能会更复杂,特别是如果您希望Erlang代码在Book结构上运行。

或者,您可以维护一个BookHandle列表并传递对此列表中项目的引用(索引或指针本身就像您当前所做的那样,但在反序列化时检查它确实在列表中)。这将解决第一个问题。

第二个问题更棘手。解决方案是link负责给定Book的Erlang进程,如果此进程退出,则删除Book。不幸的是,用于链接的API在C端并不存在。因此,您需要从Erlang端链接(或者只需尝试disabled C code发送LINK和UNLINK消息)。 C节点应该将每个已分配的Book关联到它们各自的Erlang pid所有者,如果它收到一条表明所有者进程死亡的EXIT消息,则释放这些指针。

作为附注,使用Erlang生成XLSX文件(Office Open XML)非常简单,并且不需要外部库。