我有一个C函数,我想通过NIF导出。它接受并操作自定义数据结构,std::vectors
等。
我对Elixir类型和C类型之间的转换顺序感到困惑。
我知道enif_make_resource()
、enif_release_resource()
和enif_open_resource_type()
返回数据时必须使用它们吗?还是只在解析传入参数时使用?
部分代码:
static int nif_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) {
ErlNifResourceType* rt = enif_open_resource_type(env, nullptr, "vector_of_my_struct_s1",
vec1_dtor, ERL_NIF_RT_CREATE, nullptr);
if (rt == nullptr) {
return -1;
}
assert(vec1_res == nullptr);
vec1_res = rt;
return 0;
}
ERL_NIF_INIT(Elixir.MyApp, nif_funcs, nif_load, nullptr, nullptr, nullptr);
和功能:
ERL_NIF_TERM do_cpp_calculations_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
// [........for now, parsing incoming arguments is skipped...]
std::vector<MyStructS1> native_res1 = do_cpp_calculations1(....);
ERL_NIF_TERM term;
// how to return 'native_res1' ?
// do I have to I use these functions at all?
// enif_alloc_resource(...) ?
// enif_make_resource(..) ?
// and how?
return term;
}
1条答案
按热度按时间uemypmqf1#
In the doc and this module from the official repo you have examples on how to do it.
Usually the steps you need are:
Sometimes you do both in the same function.
Create empty resource:
Example from the doc:
I'd recommend releasing the resource immediately and relying on the GC for the destructor, which should free the vector memory (you should make
std::vector
useenif_alloc
to manage the memory), so in the end you may have something along the lines of:Operate with the resource
In order to work with it, you only need to extract the pointer from the resource:
Keep in mind that you don't need to create a new resource nor return it again if you don't want to, you're modifying the memory pointed by it.
Wrapping a
std:vector
in a resourceYou may have noticed that in the snippets above I used only 'resource' and not 'vector', you have a choice there (my C++ is a bit rusty, though, so take the following with a grain of salt):
You can have the resource hold a pointer to the vector (safest):
or you can have the resource be the vector (I'm not sure if this syntax is allowed, but you get the idea):