首先,我对 C++ 不是很有经验,所以也许我正在监督这里的某些事情。 我正在尝试使用以下代码从 .proto 文件动态生成 protobuf 消息:
int init_msg(const std::string & filename, protobuf::Arena* arena, protobuf::Message** new_msg){
using namespace google::protobuf;
using namespace google::protobuf::compiler;
DiskSourceTree source_tree;
source_tree.MapPath("file", filename);
MuFiErCo error_mist;
Importer imp(&source_tree, &error_mist);
printf("Lade Datei:%s \n", filename.c_str());
const FileDescriptor* f_desc = imp.Import("file");
const Descriptor* desc = f_desc->FindMessageTypeByName("TestNachricht");
const Message* new_msg_proto = dmf.GetPrototype(desc);
*new_msg = new_msg_proto->New(arena);
//Debug
cout << (*new_msg)->GetTypeName() << endl;
return 0;
}
int main(int argc, char* argv[]){
protobuf::Arena arena;
protobuf::Message *adr2, *adr1;
init_msg("schema-1.proto", &arena, &adr1);
init_msg("schema-1.proto", &arena, &adr2);
printf("MSG_Pointer: %p, %p\n", adr1, adr2);
cout << adr1->GetTypeName() << endl;
arena.Reset();
return 0;
}
我想如果我使用 Arena,新消息也可以在函数范围之外使用。 但是,如果我尝试访问消息,总会出现段错误。 我想这是一个简单的错误,但我想不出如何解决这个问题。
这是输出:
Lade Datei:schema-1.proto
packet.TestNachricht
Lade Datei:schema-1.proto
packet.TestNachricht
MSG_Pointer: 0x1b293b0, 0x1b287f0
Speicherzugriffsfehler (Speicherabzug geschrieben)
最佳答案
The problem, I think, is that FileDescriptor et al are destroyed when init_msg returns, leaving the newly created message with no way to interrogate its .proto definition. You'd need to move Importer instance to main and keep it alive. This has nothing to do with arenas. – Igor Tandetnik
这就是解决方案。
下面是一些工作示例代码
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <memory>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/message.h>
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/arena.h>
using namespace std;
using namespace google::protobuf;
class MuFiErCo : public compiler::MultiFileErrorCollector
{
public:
void AddError(const string & filename, int line, int column, const string & message){
printf("Err: %s\n", message.c_str());
}
void AddWarning(const string & filename, int line, int column, const string & message){
printf("Warn: %s\n", message.c_str());
}
};
compiler::Importer* init_proto_dir(Arena* arena, const std::string &root_dir){
using namespace compiler;
static DiskSourceTree source_tree;
source_tree.MapPath("", root_dir);
static MuFiErCo error_mist;
static Importer* imp = Arena::Create<Importer>(arena, &source_tree, &error_mist);
return imp;
}
void init_proto_def(compiler::Importer* imp, const std::string &proto_file){
using namespace compiler;
imp->Import(proto_file);
return;
}
Message* init_msg(compiler::Importer* imp, Arena* arena, const std::string &msg_name){
const DescriptorPool* pool = imp->pool();
static DynamicMessageFactory dmf;
const Descriptor* desc = pool->FindMessageTypeByName(msg_name);
const Message* msg_proto = dmf.GetPrototype(desc);
return msg_proto->New(arena);
}
int set_value(Message* msg, const char* value_name, unsigned long int value){
const Message::Reflection* reflec = msg->GetReflection();
const Descriptor* desc = msg->GetDescriptor();
const FieldDescriptor* fdesc = desc->FindFieldByName(value_name);
reflec->SetUInt64(msg, fdesc, value);
return 0;
}
int main(int argc, char* argv[]){
Arena arena;
compiler::Importer* imp = init_proto_dir(&arena, "");
init_proto_def(imp, "schema-1.proto");
Message* msg = init_msg(imp, &arena, "packet.TestNachricht");
set_value(msg, "zahl", 23434);
cout << msg->DebugString() << endl;
return 0;
}
关于c++ - 动态生成protobuf Message并返回指向它的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42511514/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数
所以我开始关注ruby,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出
我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些
有这些railscast。http://railscasts.com/episodes/218-making-generators-in-rails-3有了这个,你就会知道如何创建样式表和脚手架生成器。http://railscasts.com/episodes/216-generators-in-rails-3通过这个,您可以了解如何添加一些文件来修改脚手架View。我想把两者结合起来。我想创建一个生成器,它也可以创建脚手架View。有点像RyanBates漂亮的生成器或web_app_themegem(https://github.com/pilu/web-app-theme)。我