【问题标题】:Protobuf message and memcpy inside erlang niferlang nif 中的 Protobuf 消息和 memcpy
【发布时间】:2012-11-18 18:51:19
【问题描述】:

我在 nif 函数 (erlang nif) 中使用 protobuf,需要创建 protobuf 消息类型的资源。我写了这样的东西:

ERL_NIF_TERM create_resource(ErlNifEnv *env, const MyClass &msg)
{
    size_t size = sizeof(MyClass);

    MyClass *class = (MyClass *)enif_alloc_resource(MY_CLASS, size);

    memcpy(class, &msg, size);
    // class->CopyFrom(&msg);

    ERL_NIF_TERM term = enif_make_resource(env, class);
    enif_release_resource(class);

    return term;
}

问题是.. 像这样复制 protobuf 消息是否合法,并且在清理时只需释放它:

  delete pointer

? 似乎一切都在这里,但我不舒尔,因为复制对象的构造函数没有被调用,并且可能有一些带有静态变量等的魔法...... 另外..我需要在 memcpy 之后调用 CopyFrom 吗?

更新:MyClass 是 C++ 类而不是 C

【问题讨论】:

  • 我的朋友建议我不要从类对象中获取资源,而最好从对象上的指针中获取资源。我会尝试这种方法。通过这种方式,我将确保正确调用构造函数和析构函数。
  • 嘿,顺便说一句,我不知道你为什么要使用协议缓冲区,但如果你需要 erlang 兼容性,总有 piqi:piqi.org

标签: erlang protocol-buffers memcpy erlang-nif


【解决方案1】:

enif_alloc_resource、enif_release_resource 和 enif_make_resource 为您完成所有的内存管理。您可以通过将资源类型设置为指针来使其更容易一些,在这种情况下,您可以从定义的资源析构函数(调用 enif_open_resource_type 时传递的函数指针)中调用 delete。

就您使用 memcpy 所做的事情而言,它对于复杂对象并不安全。例如,如果您的类成员之一是指向动态分配资源的指针,该资源在其析构函数中销毁,并且您对其进行 memcpy,则两个对象现在共享同一资源。当其中一个对象被销毁(超出范围,删除操作符)时,另一个对象会留下一个指向已释放内存的指针。

如果你有一个复杂的类,这就是你定义复制和赋值构造函数的原因。事实上,我猜 CopyFrom 应该是你的赋值和复制构造函数。

【讨论】:

    猜你喜欢
    • 2011-03-25
    • 2016-10-06
    • 1970-01-01
    • 2015-01-02
    • 2019-03-12
    • 1970-01-01
    • 2020-05-17
    • 2012-01-07
    • 2016-03-30
    相关资源
    最近更新 更多