前言
从头开始自学caffe,首先是把整个工程放在CLion里面编译,方便查看调试跳转代码。
正文
根据对网上的资料(包括但是不局限于其他博主发表的文章)学习,以及对于caffe.proto和caffe.pb.h观察发现:
1.在caffe.proto设定了caffe中各个基础类的参数
2.类的结构在caffe.proto中的格式是
message classname
{
optional Parameter1Type Parameter1=1;
repeated string input = 3
required Parameter3Type Parameter3=20;
...
... ParameterNType ParameterN=100;
}
上面这个结构中的字段可以这么理解第一个字段可以是optional,repeated,required 第二个字段是数据类型,第三个是变量名称,最后=后面的数字可以理解为ID好,在这个message中每个Parameter的ID是唯一的。生成后这些Parameter就是这个类的成员变量的名字了。然后第一个字段的三个限定词的区别是:optional表示一个普通的字段,可以有初始值,也可以不设置,不重复(生成后是一个单一的成员变量);repeated表示一个重复的字段,类似于数组的形式,所以他生成后的操作函数会有index这个参数;required也表示一个单一的字段(生成后也是一个单一的成员变量),与optional的区别就是它必须要有初始值。
3. 类的结构在生成后在caffe.pb.h中的结构是这样子的
class classname : public ::google::protobuf::Message//看来还顺便继承了一波它的基类
{
public:
classname();
virtual ~classname();
classname(const classname& from);
inline classname& operator=(const classname& from)
{
CopyFrom(from);
return *this;
}
......//此处省略类初始化的一些函数
// optional Parameter1Type Parameter1= 1;
bool has_Parameter1() const;
void clear_Parameter1();
static const int kParameter1FieldNumber = 1;
const Parameter1Type& Parameter1() const;
void set_Parameter1(const Parameter1Type& value);
Parameter1Type* mutable_Parameter1();
Parameter1Type* release_Parameter1();
void set_allocated_Parameter1(Parameter1Type* Parameter1);
// repeated string input = 3;
int input_size() const;
void clear_input();
static const int kInputFieldNumber = 3;
const ::std::string& input(int index) const;
::std::string* mutable_input(int index);
void set_input(int index, const ::std::string& value);
void set_input(int index, const char* value);
void set_input(int index, const char* value, size_t size);
::std::string* add_input();
void add_input(const ::std::string& value);
void add_input(const char* value);
void add_input(const char* value, size_t size);
const ::google::protobuf::RepeatedPtrField< ::std::string>& input() const;
::google::protobuf::RepeatedPtrField< ::std::string>* mutable_input();
...//此处省略余下参数的操作函数,仅仅以上者两个例子做说明
}
可以根据上述代码片段判断,如果是optional开头和required开头的话,那么就会生成类似与has_ clear_ set_ 等操作函数。感觉还挺厉害的。如果是repeated开头,增加了set_input和add_input,并且对于其中的成员来说多了一个index的参数,说明它在逻辑上是类似于数组的形式。
4.另外值得说明的一点是,这个proto的生成过程是严格按照id来的,从小到大生成。
5.并且,proto生成.pb.h的过程中也会对一些一只的诸如std::string构造对应输入char*的操作函数。
参考
https://blog.csdn.net/fengbingchun/article/details/49977903
https://blog.csdn.net/haima1998/article/details/78950106
https://blog.csdn.net/fengbingchun/article/details/55267162?utm_source=blogxgwz0
感谢上述博客博主的无私奉献。