将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法

Casting complex, non-primitive C++ data types into Erlang/Elixir format, to export methods using NIF

本文关键字:格式 Elixir 方法 NIF Erlang 复杂 C++ 类型转换 数据      更新时间:2023-10-16

我正在用C++编写一个库,我将在Elixir/Erlang中使用。有C++接受和返回的方法,包括通过 out 参数,并涉及指针、数据结构或库中std库,例如:元组、向量、优先级队列、位集等。以及接受或返回泛型的方法。或者我自己的自定义数据结构。

如何导出此类方法?

template<class T1>
std::array<MyStruc1, 24> my_func(
const T1& a1,
int b1,
int c1,
unordered_map<MyStruc1, double>& d1,
unordered_map<MyStruc2, int>* e1=nullptr) {
///////
}

我熟悉并找到了转换简单结构的示例:char*、简单结构和仅基元类型。

在 Erlang 中,类型是这里定义的内容。内部 Erlang 和 C/C++ std 表示形式不匹配,例如,您不能从 C 返回int64_t并直接从 Erlang 使用它。

复杂结构也一样,PrioryQueue是 Erlanglist()还是{list(), pos_integer()}

这意味着您需要使用enif_get_*enif_make_*erl_nif 函数来回转换类型。对于非常复杂的结构,这可能很乏味,因此您确实需要考虑使用资源对象是否还不够。

资源对象只是指向内存的指针,因此对于 Erlang 来说是不透明的。您可以让此不透明保留指向优先级队列内存的指针,并包括将 Erlang 术语put/2get/2

队列的方法。为什么需要erl_nif的功能?

Erlang 具有动态类型,其中变量持有的每个引用都包含其类型(在直接术语的值中,或在引用术语的引用中(,而 C/C++ 具有静态类型,其中变量是仅在编译时声明类型的变量。

对于 C/C++,0xfabada可以是intuintchar*、指向自定义结构的void*......

陈述不匹配的其他原因包括:

  1. Erlang 的整数具有可变大小
  2. Erlang 术语被标记(引用的某些位指示类型(
  3. C/C++中最接近原子的是枚举,它们完全不同
  4. 二进制
  5. 文件(短二进制文件和长二进制文件(和子二进制文件
  6. 内存管理 ...等等。