我是Erlang爱好者,也是Erlang Prorammer的新手。
我最近不得不在Erlang中面对一个数据处理问题。因此,我决定使用NIF。我有两个proplist列表,并且我必须返回基于一个术语的两个proplists的散列联接。
为了实现它,我决定在C中学习二进制操作。此外,我正在使用nippp库(C++11)来简化我的学习体验。来源:https://github.com/goertzenator/nifpp
以下是我可以想到的用于提取二进制文件并将其复制到另一个ErlNifBinary的代码,该代码已被充分记录。但我无法操纵它。
ErlNifBinary ebin, bin_term;
nifpp::get_throws(env, argv[0], ebin); // Assigns ebin to the input binary
enif_alloc_binary(16, &bin_term); // Size of new binary
memcpy(bin_term.data, ebin.data, ebin.size); // Copying the contents of binary
我有一个指向bin_term.data
中的unsigned char
的指针。如何更改bin_term.data
中的内容?
此外,如果我返回现有的复制二进制文件,考虑到我刚刚处理了输入中的数据,我会为同一个输入获得不同的输出,而不是等于输入。return enif_make_binary(env, &bin_term);
在erlang REPL中,如果我用参数<<7>>
或任何其他二进制执行函数,每次都会得到<<7,127,128,29,0,0,0,0,1,0,0,0,24,1,0,0>>
或一些随机动态值的结果。有人能指出代码中的错误吗。
首先,初始化bin_term
时,使用静态大小为16
字节。这就是为什么您的函数总是返回比预期大的二进制值(如果计算的话,是16位数字)。所以,您可以做的第一件事是用Erlang传递的二进制大小创建bin_term
enif_alloc_binary(16, &bin_term); // Constant size
enif_alloc_binary(ebin.size, &bin_term); // Same size as binary from Erlang
在nifpp
中,ErlNifBinary上有一个名为bianry
的包装器,用它可以简单地编写
binary bin_term = new binary(ebin.size);
甚至可以添加自己的复制构造函数。
其次,这是访问二进制数据。如果您查看ErlNifBinary
是如何定义的,您可以看到所有数据都可以通过data
字段访问(正如您所期望的),该字段是指向unsigned char
的指针(换句话说,数组的长度由size
字段给定)。
因此,如果你想增加并打印这个二进制文件中的每个值,你可以做这样的
ErlNifBinary ebin, bin_term;
nifpp::get_throws(env, argv[0], ebin); // Assigns ebin to the input binary
enif_alloc_binary(ebin.size, &bin_term); // Size of new binary
memcpy(bin_term.data, ebin.data, ebin.size); // Copying the contents of binary
for(int i=0; i<bin_term.size; ++i){
bin_term.data[i] = bin_term.data[i] + 1;
std::cout << bin_term.data[i] << std::endl;
}
如果您需要除字符数组(原始内存)之外的其他数据表示,您可以查看Resource对象,这些对象本质上是指向C内存的智能指针(垃圾收集),可以在Erlang中传递。