caffe.cpp源代码不在累赘,这里提供一下caffe代码中的序列化消息的使用,caffe中的数据结构使用的序列化消息实现数据之间的存储和传送。先举个例子,然后提供一下caffe源代码中的代码案例;
文件名字为msg.proto
package test;
message msg
{required int32 id=1 ;
required string str=2;
optional string sex=3;
}
Required: 表示是一个必须字段,必须相对于发送方,在发送消息之前必须设置该字段的值,对于接收方,必须能够识别该字段的意思。发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃。
Optional:表示是一个可选字段,可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。对于接收方,如果能够识别可选字段就进行相应的处理,如果无法识别,则忽略该字段,消息中的其它字段正常处理。—因为optional字段的特性,很多接口在升级版本中都把后来添加的字段都统一的设置为optional字段,这样老的版本无需升级程序也可以正常的与新的软件进行通信,只不过新的字段无法识别而已,因为并不是每个节点都需要新的功能,因此可以做到按需升级和平滑过渡。
Repeated:表示该字段可以包含0~N个元素。其特性和optional一样,但是每一次可以包含多个值。可以看作是在传递一个数组的值。
字段名称的命名与C、C++、Java等语言的变量命名方式几乎是相同的。
protobuf建议字段的命名采用以下划线分割,例如 first_name .
ubuntu@ubuntu:~$ protoc -I=./ --cpp_out=./ ./msg.proto
生成了这两个文件msg.pb.cc和msg.pb.h
文件msg.pb.h
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: msg.proto
#ifndef PROTOBUF_msg_2eproto__INCLUDED
#define PROTOBUF_msg_2eproto__INCLUDED
#include <string>
#include <google/protobuf/stubs/common.h>
#if GOOGLE_PROTOBUF_VERSION < 2005000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/unknown_field_set.h>
// @@protoc_insertion_point(includes)
namespace test {
// Internal implementation detail -- do not call these.
void protobuf_AddDesc_msg_2eproto();
void protobuf_AssignDesc_msg_2eproto();
void protobuf_ShutdownFile_msg_2eproto();
class msg;
// ===================================================================
class msg : public ::google::protobuf::Message {
public:
msg();
virtual ~msg();
msg(const msg& from);
inline msg& operator=(const msg& from) {
CopyFrom(from);
return *this;
}
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
static const ::google::protobuf::Descriptor* descriptor();
static const msg& default_instance();
void Swap(msg* other);
// implements Message ----------------------------------------------
msg* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
void CopyFrom(const msg& from);
void MergeFrom(const msg& from);
void Clear();
bool IsInitialized() const;
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
public:
::google::protobuf::Metadata GetMetadata() const;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
// required int32 id = 1;
inline bool has_id() const;
inline void clear_id();
static const int kIdFieldNumber = 1;
inline ::google::protobuf::int32 id() const;
inline void set_id(::google::protobuf::int32 value);
// required string str = 2;
inline bool has_str() const;
inline void clear_str();
static const int kStrFieldNumber = 2;
inline const ::std::string& str() const;
inline void set_str(const ::std::string& value);
inline void set_str(const char* value);
inline void set_str(const char* value, size_t size);
inline ::std::string* mutable_str();
inline ::std::string* release_str();
inline void set_allocated_str(::std::string* str);
// optional string sex = 3;
inline bool has_sex() const;
inline void clear_sex();
static const int kSexFieldNumber = 3;
inline const ::std::string& sex() const;
inline void set_sex(const ::std::string& value);
inline void set_sex(const char* value);
inline void set_sex(const char* value, size_t size);
inline ::std::string* mutable_sex();
inline ::std::string* release_sex();
inline void set_allocated_sex(::std::string* sex);
// @@protoc_insertion_point(class_scope:test.msg)
private:
inline void set_has_id();
inline void clear_has_id();
inline void set_has_str();
inline void clear_has_str();
inline void set_has_sex();
inline void clear_has_sex();
::google::protobuf::UnknownFieldSet _unknown_fields_;
::std::string* str_;
::std::string* sex_;
::google::protobuf::int32 id_;
mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
friend void protobuf_AddDesc_msg_2eproto();
friend void protobuf_AssignDesc_msg_2eproto();
friend void protobuf_ShutdownFile_msg_2eproto();
void InitAsDefaultInstance();
static msg* default_instance_;
};
// ===================================================================
// ===================================================================
// msg
// required int32 id = 1;
inline bool msg::has_id() const {
return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void msg::set_has_id() {
_has_bits_[0] |= 0x00000001u;
}
inline void msg::clear_has_id() {
_has_bits_[0] &= ~0x00000001u;
}
inline void msg::clear_id() {
id_ = 0;
clear_has_id();
}
inline ::google::protobuf::int32 msg::id() const {
return id_;
}
inline void msg::set_id(::google::protobuf::int32 value) {
set_has_id();
id_ = value;
}
// required string str = 2;
inline bool msg::has_str() const {
return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void msg::set_has_str() {
_has_bits_[0] |= 0x00000002u;
}
inline void msg::clear_has_str() {
_has_bits_[0] &= ~0x00000002u;
}
inline void msg::clear_str() {
if (str_ != &::google::protobuf::internal::kEmptyString) {
str_->clear();
}
clear_has_str();
}
inline const ::std::string& msg::str() const {
return *str_;
}
inline void msg::set_str(const ::std::string& value) {
set_has_str();
if (str_ == &::google::protobuf::internal::kEmptyString) {
str_ = new ::std::string;
}
str_->assign(value);
}
inline void msg::set_str(const char* value) {
set_has_str();
if (str_ == &::google::protobuf::internal::kEmptyString) {
str_ = new ::std::string;
}
str_->assign(value);
}
inline void msg::set_str(const char* value, size_t size) {
set_has_str();
if (str_ == &::google::protobuf::internal::kEmptyString) {
str_ = new ::std::string;
}
str_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* msg::mutable_str() {
set_has_str();
if (str_ == &::google::protobuf::internal::kEmptyString) {
str_ = new ::std::string;
}
return str_;
}
inline ::std::string* msg::release_str() {
clear_has_str();
if (str_ == &::google::protobuf::internal::kEmptyString) {
return NULL;
} else {
::std::string* temp = str_;
str_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
return temp;
}
}
inline void msg::set_allocated_str(::std::string* str) {
if (str_ != &::google::protobuf::internal::kEmptyString) {
delete str_;
}
if (str) {
set_has_str();
str_ = str;
} else {
clear_has_str();
str_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
}
}
// optional string sex = 3;
inline bool msg::has_sex() const {
return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void msg::set_has_sex() {
_has_bits_[0] |= 0x00000004u;
}
inline void msg::clear_has_sex() {
_has_bits_[0] &= ~0x00000004u;
}
inline void msg::clear_sex() {
if (sex_ != &::google::protobuf::internal::kEmptyString) {
sex_->clear();
}
clear_has_sex();
}
inline const ::std::string& msg::sex() const {
return *sex_;
}
inline void msg::set_sex(const ::std::string& value) {
set_has_sex();
if (sex_ == &::google::protobuf::internal::kEmptyString) {
sex_ = new ::std::string;
}
sex_->assign(value);
}
inline void msg::set_sex(const char* value) {
set_has_sex();
if (sex_ == &::google::protobuf::internal::kEmptyString) {
sex_ = new ::std::string;
}
sex_->assign(value);
}
inline void msg::set_sex(const char* value, size_t size) {
set_has_sex();
if (sex_ == &::google::protobuf::internal::kEmptyString) {
sex_ = new ::std::string;
}
sex_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* msg::mutable_sex() {
set_has_sex();
if (sex_ == &::google::protobuf::internal::kEmptyString) {
sex_ = new ::std::string;
}
return sex_;
}
inline ::std::string* msg::release_sex() {
clear_has_sex();
if (sex_ == &::google::protobuf::internal::kEmptyString) {
return NULL;
} else {
::std::string* temp = sex_;
sex_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
return temp;
}
}
inline void msg::set_allocated_sex(::std::string* sex) {
if (sex_ != &::google::protobuf::internal::kEmptyString) {
delete sex_;
}
if (sex) {
set_has_sex();
sex_ = sex;
} else {
clear_has_sex();
sex_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
}
}
// @@protoc_insertion_point(namespace_scope)
} // namespace test
#ifndef SWIG
namespace google {
namespace protobuf {
} // namespace google
} // namespace protobuf
#endif // SWIG
// @@protoc_insertion_point(global_scope)
#endif // PROTOBUF_msg_2eproto__INCLUDED
文件msg.pb.cc
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: msg.proto
#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
#include "msg.pb.h"
#include <algorithm>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// @@protoc_insertion_point(includes)
namespace test {
namespace {
const ::google::protobuf::Descriptor* msg_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
msg_reflection_ = NULL;
} // namespace
void protobuf_AssignDesc_msg_2eproto() {
protobuf_AddDesc_msg_2eproto();
const ::google::protobuf::FileDescriptor* file =
::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
"msg.proto");
GOOGLE_CHECK(file != NULL);
msg_descriptor_ = file->message_type(0);
static const int msg_offsets_[3] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(msg, id_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(msg, str_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(msg, sex_),
};
msg_reflection_ =
new ::google::protobuf::internal::GeneratedMessageReflection(
msg_descriptor_,
msg::default_instance_,
msg_offsets_,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(msg, _has_bits_[0]),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(msg, _unknown_fields_),
-1,
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(msg));
}
namespace {
GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
inline void protobuf_AssignDescriptorsOnce() {
::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
&protobuf_AssignDesc_msg_2eproto);
}
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
msg_descriptor_, &msg::default_instance());
}
} // namespace
void protobuf_ShutdownFile_msg_2eproto() {
delete msg::default_instance_;
delete msg_reflection_;
}
void protobuf_AddDesc_msg_2eproto() {
static bool already_here = false;
if (already_here) return;
already_here = true;
GOOGLE_PROTOBUF_VERIFY_VERSION;
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
"\n\tmsg.proto\022\004test\"+\n\003msg\022\n\n\002id\030\001 \002(\005\022\013\n\003"
"str\030\002 \002(\t\022\013\n\003sex\030\003 \001(\t", 62);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"msg.proto", &protobuf_RegisterTypes);
msg::default_instance_ = new msg();
msg::default_instance_->InitAsDefaultInstance();
::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_msg_2eproto);
}
// Force AddDescriptors() to be called at static initialization time.
struct StaticDescriptorInitializer_msg_2eproto {
StaticDescriptorInitializer_msg_2eproto() {
protobuf_AddDesc_msg_2eproto();
}
} static_descriptor_initializer_msg_2eproto_;
// ===================================================================
#ifndef _MSC_VER
const int msg::kIdFieldNumber;
const int msg::kStrFieldNumber;
const int msg::kSexFieldNumber;
#endif // !_MSC_VER
msg::msg()
: ::google::protobuf::Message() {
SharedCtor();
}
void msg::InitAsDefaultInstance() {
}
msg::msg(const msg& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
}
void msg::SharedCtor() {
_cached_size_ = 0;
id_ = 0;
str_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
sex_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
msg::~msg() {
SharedDtor();
}
void msg::SharedDtor() {
if (str_ != &::google::protobuf::internal::kEmptyString) {
delete str_;
}
if (sex_ != &::google::protobuf::internal::kEmptyString) {
delete sex_;
}
if (this != default_instance_) {
}
}
void msg::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* msg::descriptor() {
protobuf_AssignDescriptorsOnce();
return msg_descriptor_;
}
const msg& msg::default_instance() {
if (default_instance_ == NULL) protobuf_AddDesc_msg_2eproto();
return *default_instance_;
}
msg* msg::default_instance_ = NULL;
msg* msg::New() const {
return new msg;
}
void msg::Clear() {
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
id_ = 0;
if (has_str()) {
if (str_ != &::google::protobuf::internal::kEmptyString) {
str_->clear();
}
}
if (has_sex()) {
if (sex_ != &::google::protobuf::internal::kEmptyString) {
sex_->clear();
}
}
}
::memset(_has_bits_, 0, sizeof(_has_bits_));
mutable_unknown_fields()->Clear();
}
bool msg::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
::google::protobuf::uint32 tag;
while ((tag = input->ReadTag()) != 0) {
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
// required int32 id = 1;
case 1: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
input, &id_)));
set_has_id();
} else {
goto handle_uninterpreted;
}
if (input->ExpectTag(18)) goto parse_str;
break;
}
// required string str = 2;
case 2: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
parse_str:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_str()));
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->str().data(), this->str().length(),
::google::protobuf::internal::WireFormat::PARSE);
} else {
goto handle_uninterpreted;
}
if (input->ExpectTag(26)) goto parse_sex;
break;
}
// optional string sex = 3;
case 3: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
parse_sex:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_sex()));
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->sex().data(), this->sex().length(),
::google::protobuf::internal::WireFormat::PARSE);
} else {
goto handle_uninterpreted;
}
if (input->ExpectAtEnd()) return true;
break;
}
default: {
handle_uninterpreted:
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
return true;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
break;
}
}
}
return true;
#undef DO_
}
void msg::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// required int32 id = 1;
if (has_id()) {
::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->id(), output);
}
// required string str = 2;
if (has_str()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->str().data(), this->str().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
::google::protobuf::internal::WireFormatLite::WriteString(
2, this->str(), output);
}
// optional string sex = 3;
if (has_sex()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->sex().data(), this->sex().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
::google::protobuf::internal::WireFormatLite::WriteString(
3, this->sex(), output);
}
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
}
::google::protobuf::uint8* msg::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// required int32 id = 1;
if (has_id()) {
target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->id(), target);
}
// required string str = 2;
if (has_str()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->str().data(), this->str().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
2, this->str(), target);
}
// optional string sex = 3;
if (has_sex()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->sex().data(), this->sex().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
3, this->sex(), target);
}
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
return target;
}
int msg::ByteSize() const {
int total_size = 0;
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// required int32 id = 1;
if (has_id()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::Int32Size(
this->id());
}
// required string str = 2;
if (has_str()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->str());
}
// optional string sex = 3;
if (has_sex()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->sex());
}
}
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
unknown_fields());
}
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = total_size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
return total_size;
}
void msg::MergeFrom(const ::google::protobuf::Message& from) {
GOOGLE_CHECK_NE(&from, this);
const msg* source =
::google::protobuf::internal::dynamic_cast_if_available<const msg*>(
&from);
if (source == NULL) {
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
MergeFrom(*source);
}
}
void msg::MergeFrom(const msg& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_id()) {
set_id(from.id());
}
if (from.has_str()) {
set_str(from.str());
}
if (from.has_sex()) {
set_sex(from.sex());
}
}
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}
void msg::CopyFrom(const ::google::protobuf::Message& from) {
if (&from == this) return;
Clear();
MergeFrom(from);
}
void msg::CopyFrom(const msg& from) {
if (&from == this) return;
Clear();
MergeFrom(from);
}
bool msg::IsInitialized() const {
if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;
return true;
}
void msg::Swap(msg* other) {
if (other != this) {
std::swap(id_, other->id_);
std::swap(str_, other->str_);
std::swap(sex_, other->sex_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
std::swap(_cached_size_, other->_cached_size_);
}
}
::google::protobuf::Metadata msg::GetMetadata() const {
protobuf_AssignDescriptorsOnce();
::google::protobuf::Metadata metadata;
metadata.descriptor = msg_descriptor_;
metadata.reflection = msg_reflection_;
return metadata;
}
// @@protoc_insertion_point(namespace_scope)
} // namespace test
// @@protoc_insertion_point(global_scope)
文件名字为reader.cpp
#include<iostream>
#include<fstream>
#include"msg.pb.h"
using namespace std;
int main(int argc,char* argv[])
{ test::msg obj;
fstream input("./log",ios::in|ios::binary);
obj.ParseFromIstream(&input);
cout<<obj.id()<<endl;
cout<<obj.str()<<endl;
return 0;}
文件名字为writer.cpp
#include<fstream>
#include<iostream>
#include"msg.pb.h"
using namespace std;
int main(int argc,char* argv[])
{test::msg obj;
obj.set_id(120);
obj.set_str("i am a student");
fstream output("./log",ios::out|ios::binary);
obj.SerializeToOstream(&output);
return 0;}
ubuntu@ubuntu:~$ protoc -I=./ --cpp_out=./ ./msg.proto
ubuntu@ubuntu:~$ g++ msg.pb.cc reader.cpp -o reader `pkg-config --cflags --libs protobuf` -lpthread
ubuntu@ubuntu:~$ g++ msg.pb.cc writer.cpp -o writer `pkg-config --cflags --libs protobuf` -lpthread
ubuntu@ubuntu:~$ ./writer
ubuntu@ubuntu:~$ ./reader
120
i am a student
完成了数据从write 到read的操作;
在caffe源代码进行编译过程中,首先把/caffe/src/caffe/proto/caffe.proto 编译成caffe/build/src/caffe/proto/caffe.pb.cc和caffe/build/src/caffe/proto/caffe.pb.h序列化文件,然后在caffe.cpp中使用序列化的变量;我们只需读懂/caffe/src/caffe/proto/caffe.proto文件即可,按照阅读代码需要,查阅这个函数的变量即可;列如
caffe::SolverParameter solver_param;//源代码中的定义消息;caffe 表示包名; SolverParameter表示消息名; solver_param 表示定义的变量名;