Сообщение Protobuf и memcpy внутри erlang nif

Я использую protobuf внутри функции nif (erlang nif), и мне нужно создать ресурс типа сообщения 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

? Кажется, что здесь все правильно, но я не уверен, потому что конструктор копируемого объекта не был вызван, и может быть есть какая-то магия со статическими переменными и т. Д. Также.. мне нужно вызвать CopyFrom после memcpy ?

upd: MyClass - это класс C++, а не C


person Def_NulL    schedule 30.11.2012    source источник
comment
Мой друг посоветовал мне не делать ресурс из объекта класса, а лучше из указателя на объект. Я попробую этот подход. Таким образом, я буду уверен, что и конструктор, и деструктор будут вызываться правильно.   -  person Def_NulL    schedule 30.11.2012
comment
Эй, кстати, я не уверен, почему вы используете буферы протокола, но если вам нужна совместимость с erlang, всегда есть piqi: piqi.org   -  person Soup d'Campbells    schedule 01.02.2013


Ответы (1)


enif_alloc_resource, enif_release_resource и enif_make_resource выполняют все управление памятью за вас. Вы можете сделать это несколько проще, сделав свой тип ресурса указателем, и в этом случае вы вызываете удаление из своего определенного деструктора ресурса (указатель функции, который вы передаете при вызове enif_open_resource_type).

Что касается того, что вы делаете с memcpy, это небезопасно для сложных объектов. Например, если один из членов вашего класса является указателем на динамически выделяемый ресурс, который он уничтожает в своем деструкторе, и вы запоминаете его, два объекта теперь совместно используют один и тот же ресурс. Когда один из объектов уничтожается (выпадает из области видимости, оператор удаления), другой объект остается с указателем на освобожденную память.

Вот почему вы определяете конструкторы копирования и присваивания, если у вас есть сложный класс. Я предполагаю, что CopyFrom должен быть как вашим заданием, так и конструктором копирования.

person Soup d'Campbells    schedule 26.12.2012