Глубокое копирование с ProtoBuf в C / Stack Overflow

Скажем, у меня было множество указателей, каждый из которых указывает на структуры, которые могут снова иметь указатели на другие структуры в них; Можно ли обработать сериализацию этого с помощью protobuf? Если так, то как?

Любая помощь будет принята с благодарностью.

5

Решение

То, как вы думаете об этой проблеме, противоположно тому, как вам нужно думать, если вы думаете о protobufs. Протобуфы не берут существующую структуру данных и не сериализуют их. Они берут протокол сериализации и создают структуры данных для вас, которые вы заполняете.

При этом вложенная сериализация довольно проста:

// nested.proto
message Inner {
required string value = 1;
}

message Outer {
required Inner inner = 1;
}

message Pointers {
repeated Outer outer = 1;
}

Предполагая, что вы правильно скомпилировали это, вы можете использовать этот протокол, работая извне. То есть вы начинаете с самой высокой структуры, Pointersи проложите себе путь в Inner объект:

Pointers pointers;
for (int i = 0; i < 10; ++i) {
auto outer = pointers.add_outer();
auto inner = outer->mutable_inner();
inner->set_value(std::to_string(i));
}

std::stringstream stream;
pointers.SerializeToOstream(&stream);

...

Pointers parsed_pointers;
parsed_pointers.ParseFromIstream(&stream);
for (int i = 0; i < parsed_pointers.outer_size(); ++i) {
std::cout << parsed_pointers.outer(i).inner().value() << std::endl;
}

// This prints 0, 1, 2, ..., 9 all on their own lines

Можно начать с Inner сообщение, но способ передачи права собственности на Outer сообщение не так просто или очевидно:

Inner* inner = new Inner();
inner->set_value("Hello world");
Outer outer;
outer.set_allocated_inner(inner);

Вызов этого метода захватит право собственности на inner указатель, так что вы не должны вручную delete это сам.

6

Другие решения

Есть еще один метод, который я считаю полезным. поскольку .set_allocated_*(A) имеет побочный эффект, который разрушит A, Просто скопировать из A, ты можешь попробовать .mutable_*()->CopyFrom(A),

0

По вопросам рекламы [email protected]