我如何从来自Elixir二进制字符串的ERL_NIF_TERM
中获得char*
数据?
我看到term_to_binary/1
功能,但它似乎不是正确的事情。
如NIF
文档所述
也就是说,您的二进制类型的术语是通过结构类型
ErlNifBinary
来访问的,该结构类型包含一个指向原始二进制数据的指针(data
)和数据的字节长度(size
)。数据和大小都是只读的,只能通过调用API函数来写入。然而,ErlNifBinary
的实例总是由用户分配(通常作为局部变量)。
NIF
函数应该在
旁边有一个签名。static ERL_NIF_TERM
foo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
其中argc
应该是1
,argv[0]
将是一个指向ErlNifBinary
的常量指针,相应的elixir调用将像
def foo(binary), do: :erlang.nif_error("Load NIF!")
使用NIF时,必须使用charlist和NOT Elixir二进制字符串. 使用to_charlist/1
函数将二进制字符串转换为字符列表,然后调用NIF函数
在NIF函数中,您可以像这样读取字符列表,
#define MAXBUFLEN 1024
char src[MAXBUFLEN];
enif_get_string(env, argv[0], src, MAXBUFLEN, ERL_NIF_LATIN1);
src
现在保存字符串值。
您首先需要准备ErlNifBinary
,然后使用enif_inspect_binary()
填充它。
根据NIF文档,ErlNifBinary
是一个结构体,有两个可见字段,如下所示。
typedef struct {
size_t size;
unsigned char* data;
} ErlNifBinary;
data
是您想要的char*
。enif_inspect_binary()
用二进制的信息填充ErlNifBinary
,使其数据可访问。
假设二进制字符串是nif函数的第一个参数,C代码应该是这样的:
static ERL_NIF_TERM
do_stuff_with_binary(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
unsigned char data[100];
ErlNifBinary bin;
if (!enif_inspect_binary(env, argv[0], &bin)) {
return enif_make_atom(env, "error");
}
// Do stuff with binary. Its data is now accessible via bin.data
// memcpy(data, bin.data, 100);
return enif_make_atom(env, "ok");
}