我们在带有 c# 和 c++ 代码的中型嵌入式系统中使用 Protocol Buffer (2.4.1)。我们使用 protobufs 来隔离我们的托管层和 native 层,以及一个易于维护的序列化层(出于好奇,我们本来可以使用 Pinvoke,但我们还必须在测试/模拟器上的单独进程中运行 native 代码)。
我们的系统有很多 DLL,我在它自己的 DLL 中有生成的 native protobuf 代码,这样系统的其他部分就不必直接链接到生成的代码中。
我遇到的问题是所有生成的访问器都是内联,例如:
inline const ::MyProtoClassName::MyField& MyProtoClassName::myfield() const
{
return myfield_ != NULL ? *myfield_ : *default_instance_->myfield_;
}
按大小使用生成的 API(如果未设置此特定字段,将取消引用和访问“default_instance_”)。这意味着我无法链接 (lnk2001) 任何使用访问器的客户端,因为没有符号 default_instance_
我认为 ProtoBufs 的典型用例是在生成的 protobuf 代码本身中有每个组件链接(毕竟,这主要是分布式系统的序列化层),但是
我想知道是否有一个编译开关可以改变我错过的内联行为。 (在 CC 文件中定义所有访问器,而不是 H)
谢谢!
谢谢 @g-makulik !看起来答案在 ProtoC 代码中大约有 30 行,我只是没看到它:)
正如 Kenton 的一些变更日志中所指出的,添加它会导致一些与基类相关的警告(C4251、c4275),这些基类也不是 DLLEXPORT
根据 ProtoBufs 的实现方式,并且 protobuf 类都是模板,这些警告是良性的。为了完全忽略它们(例如,不必为所有客户端禁用警告),我使用了这种有点老套的方法:
-每个人都包含的 protobuf.h 文件的包装器。 (没有包含真正生成的H文件)
#pragma once
#pragma warning(push)
#pragma warning(disable:4251)
#pragma warning(disable:4275)
// include the protobuf generated code; but exclude the warn c4251, c4275
// these relate to the dll exported
#include "yourProtoFile.h"
#pragma warning(pop)
和一个包装器 C 文件(真正的 protobuf CC 文件不在我的项目中 -> 不是直接构建的)
#include "MyProtoFile_WRAPPER.h"
#include "MyProtoFile.cc"
最佳答案
我认为此链接可以回答您的问题:Protobuf with MSVC: how to export generated Message
引用自 Kenon Varga(google protobuf 项目负责人):
If you invoke protoc like:
protoc --cpp_out=dllexport_decl=MY_EXPORT_MACRO:path/to/output/dir myproto.proto
then it will generate code with MY_EXPORT_MACRO in all the right places. However, this option is incomplete -- currently there is no way to force the generated .pb.h to #include a header which defines MY_EXPORT_MACRO. I'm open to patches to fix this. Or, you could use a hack to work around it, such as adding the #include via some sort of text processing after protoc finishes, or perhaps moving the .pb.h to .pb2.h and replacing the .pb.h file with one that first includes your header then includes the .pb2.h...
此外,为了弥补提到的不完整性(引自 Aron Bierbaum):
We currently get around this limitation by forcing the the header to be included using compiler command line flags:
Windows: /FIproject/Config.h
Linux: -include project/Config.h
注意:
在这种情况下,使用 inline 关键字不应该是相关的(附加的 __declspec dllexport/__declspec dllimport 属性放在访问器方法上) .根据定义,是否内联函数取决于编译器。当然,看到 __declspec dllexport 或 __declspec dllimport 属性与内联是矛盾的。
关于c++ - Protocol Buffer - 生成非内联访问器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17980467/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我的瘦服务器配置了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',
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我正在编写一个小脚本来定位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
我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数
我正在使用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)。我