我正在关注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。
对不起,如果这没有任何意义,我是新手。
答案 0 :(得分:0)
xlCreateBook()
返回一个指针(BookHandle
实际上是指向C ++对象Book
的指针)。因此,您的代码将此指针序列化为Erlang二进制文件(可能长度为4或8个字节,具体取决于您的体系结构),并在从Erlang节点传回时对其进行反序列化。
这基本上有效。
但是,它有以下两个缺点:
Book
结构的指针。这可能会导致崩溃或更糟糕的数据损坏。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)非常简单,并且不需要外部库。