我们在带有 c# 和 c++ 代码的中型嵌入式系统中使用协议缓冲区(2.4.1)。我们使用 protobufs 来隔离我们的托管层和本机层,并带有一个易于维护的序列化层(出于好奇,我们可能只使用了 Pinvoke,但我们还必须在测试/模拟器上的单独进程中运行本机代码)。
我们的系统有很多 DLL,我在它自己的 DLL 中有生成的本机 protobuf 代码,这样系统的其他部分就不必直接链接到生成的代码中。
我遇到的问题是所有生成的访问器都是inline,例如:
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'd
使用 ProtoBufs 的实现方式,并且 protobuf 类都是模板,这些警告是良性的。为了完全忽略它们(例如,不必禁用所有客户端的警告),我使用了这种有点 hacky 的方法:
-everyone 包含的 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"