利⽤objcopy把资源⽂件编译进动态库或可执⾏⽂件
⼯作中收到⼀个需求,需要把caffe的prototxt⽂件和模型⽂件编译进动态库,以后链接了这个动态库的⼯程,不需要依赖其他资源⽂件,只需要执⾏相关函数就可以直接进⾏⼈脸跟踪。以前提供的库是库,模型是模型,⼀旦不同版本的模型和库⽂件配对出了错误,整个跟踪结果就会出现⼀些乱七⼋糟的错误,现在打包成⼀个即可彻底避免这种情况。
⾸先需要明确,资源⽂件只不过是⼀堆存储在磁盘上的⼆进制串,按照⼀定规则读⼊内存后,便会起到我们期望的作⽤。那如果事先把资源⽂件作为全局变量直接编⼊可执⾏⽂件或者动态库中,在程序执⾏过程中,再按照⼀定规则解读这段内存,当然也可以达到同样的效果。
这便需要⽤到objcopy和nm命令来实现。objcopy和nm都是Linux系统提供的命令,简单来说,objcopy可以把资源⽂件转换成.o⽂件,这样才能编译到可执⾏⽂件或者库⽂件中,⽽nm命令则⽤来解读.o⽂件的符号表,定位具体的数据地址。具体操作如下:
模型⽂件为A.caffemodel。⾸先完成准备⼯作:先利⽤caffe提供的接⼝ReadNetParamsFromTextFileOrDie将A.caffemodel读取到内存中的,以caffe::NetParameter的结构存在,再通过WriteProtoToBinaryFile函数将其写⼊磁盘,成为B.binarymodel⽂件,得到了B.binarymodel⽂件,则准备⼯作完成,只要反序列化B⽂件,就能在内存中重建caffe::NetParameter结构。
车辆损失险是什么意思接下来解决如何把B.binarymodel⽂件编⼊可执⾏⽂件的问题。⾸先⽤如下命令得到.o⽂件,-I为输⼊⽂件格式,-O为为输出⽂件格式,-B为输出的架构,这⾥采⽤的是⼆进制⽂件输出为x86 64位架构下的.o⽂件
objcopy -I binary -O elf64-x86-64 -B i386 B.binarymodel C.o
然后使⽤nm命令得到符号地址
nm C.o
一年级下册数学期中试卷结果如下:
00000000000000df D _B_caffe_binarymodel_end
00000000000000df A _B_caffe_binarymodel_size
0000000000000000 D _B_caffe_binarymodel_start
可以看到,原来的B.binarymodel被转化为⼀个char数组存储在C.o⽂件中,其中_B_caffe_binarymodel_start代表起始地
址,_B_caffe_binarymodel_end为结束地址,_B_caffe_binarymodel_size为数组长度
在最终交付的库⽂件代码中,可以通过如下⽅式来调⽤C.o⽂件中的信息,直接贴代码吧:
extern char _B_binarymodel_start[];
六级写作模板extern int _B_binarymodel_size;
caffe::NetParameter modelParam;
long modelLen = (long)&_B_binarymodel_size;
std::string modelData(_B_binarymodel_start, modelLen);
2020元旦放假安排调休modelParam.ParseFromString(modelData);
net->CopyTrainedLayersFrom(modelParam);
把caffe⽹络结构⽂件也编⼊可执⾏⽂件的⽅法类似,略去不表,贴⼀下最后调⽤的代码:
extern char _vgg16_caffe_binaryproto_start[];
extern int _vgg16_caffe_binaryproto_size;
钉钉打卡分享到照片墙怎么取消caffe::NetParameter netParam;
p6 rootlong netLen = (long)&_vgg16_caffe_binaryproto_size;
std::string netData(_vgg16_caffe_binaryproto_start, netLen);
netParam.ParseFromString(netData);
netParam.mutable_state()->set_phase(TEST);
netParam.mutable_state()->set_level(0);
有时候_B_binarymodel_size这个值获取可能会失败,⽐如代码跑在ARM平台上的时候,这时候可以使⽤_B_caffe_binarymodel_end - _B_caffe_binarymodel_start来获取长度
由于这个⽅法是把⽂件作为全局变量的形式存储在动态库中,应此⽂件⼤⼩受到全局变量最⼤⼤⼩限制。在32位操作系统上,全局变量区最⼤为4GB,故这种⽅法最多只能⽤于不⼤于4GB的资源⽂件
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论