【问题标题】:serialize in .NET, deserialize in C++在 .NET 中序列化,在 C++ 中反序列化
【发布时间】:2011-01-22 18:33:21
【问题描述】:

我有一个以二进制格式序列化对象的 .NET 应用程序。 这个对象是一个由几个字段组成的结构。

我必须反序列化并在 C++ 应用程序中使用该对象。 我不知道是否有任何 C++ 的序列化库,谷歌搜索没有出现太多。

最快的方法是什么?

提前致谢。 罗伊。

更新: 我在我的 .NET 应用程序中使用 Protobuf-net 进行了序列化,相对容易。 我还使用 GetProto() 命令获得了 protobuf-net 生成的 .proto 文件。 在 .proto 文件中,我的 GUID 字段的类型为“bcl.guid”,但 C++ protoc.exe 编译器不知道如何解释它们! 我该怎么办?

【问题讨论】:

    标签: c# c++ serialization


    【解决方案1】:

    如果您使用的是BinaryFormatter,那么这几乎是不可能的。不要去那里...

    协议缓冲区被设计为可移植、跨平台和版本容错(因此当您添加新字段等时它不会爆炸)。 Google 提供了 C++ 版本,并且有几个 C# 版本免费提供(包括我自己的)-see here for the full list

    小巧、快速、简单。

    请注意,protobuf-net 的 v1 不会直接处理结构(你需要一个 DTO 类),但 v2(很快)确实已经过测试结构支持。

    【讨论】:

    • 嗨,Marc,很抱歉滥用此评论部分,但我遇到了 protobuf-net 的问题 - 你能看看我的帖子并回答一下吗?谢谢 :) stackoverflow.com/questions/2370090/…
    • @Roey - 为引起我的注意而欢呼,但我已经有一个 RSS 提要,用于标记 protobuf-net 的任何内容;-p
    【解决方案2】:

    您可以编辑 .NET 应用程序吗?如果是这样,为什么不使用XML Serialization 以易于导入的格式输出数据?

    【讨论】:

    • 可能是最简单的方法......即使 XML 是邪恶的。
    【解决方案3】:

    boost 和 Google 都有用于序列化的库。但是,如果您的结构非常简单,您可以考虑自己管理序列化,方法是从 C# 中写入字节,然后使用 fread 在 C++ 中读取数据。

    【讨论】:

    • 当我在 .NET 中进行二进制序列化时,它不会以 C++ fread 可读的方式写入字节吗?
    • 哦,我明白你的意思了,你需要我从流中分别读取每个字段,并将其放入我的 C++ 程序中的变量中......
    • 是的,如果您的结构使用 LayoutKind.Sequential 足够简单,您可能只需在 .NET 中将整个内容都删除,然后在 C++ 中阅读一遍。这是假设您只在结构中使用 int、double 等 POD。
    【解决方案4】:

    同意其他人。这样做会使您的应用程序非常脆弱。如果您要序列化的类之一以任何方式更改或构建在更高版本的 C# 编译器上,请考虑以下情况:您的序列化类可能会发生更改,导致它们不可读。

    基于 XML 的解决方案可能运行良好。你考虑过 SOAP 吗?现在有点过时了,但值得一看。主要问题是将实现与数据分离。如果速度/效率是一个问题,您可以使用二进制文件执行此操作,尽管根据我的经验,这种情况很少发生。

    【讨论】:

      【解决方案5】:

      以二进制格式序列化并期望使用另一种语言的应用程序读取二进制文件是一个非常脆弱的解决方案(即,它往往会因为对任何事物的最小更改而中断)。

      以通用的标准格式序列化数据会更稳定。

      【讨论】:

      • 只要二进制文件采用约定的格式,它就不必根本很脆弱。但是是的 - 像 BinaryFormatter 这样的东西注定要在这里失败。
      • @Mark:是也不是。格式是基于结构的二进制表示达成一致的。如果有任何变化,例如整数的字节顺序(硬件变化)元素之间的填充(编译器中的更新)等,那么二进制结构现在不再与原始结构匹配。使用新编译器或在新机器上直接移植 C++ 程序有可能会中断。最糟糕的是,标准实现将无法检测到更改,并且可能会默默地做错事。
      • 不要忘记整数大小。在我的商店最近的一个应用程序中,我们在 32 位机器上使用 Boost.Serialization 序列化数据并在 64 位机器上对其进行反序列化,结果造成严重破坏。所以是的,二进制格式确实很脆弱。
      【解决方案6】:

      您可以选择更改格式吗?如果是这样,请考虑选择非二进制格式以获得更好的互操作性。有很多用于读写 XML 的库。 Json 也很受欢迎。

      二进制格式是高效的,但容易受到实现细节的影响(您的 C++ 编译器是否打包数据结构?整数和浮点数是如何表示的?使用什么字节顺序?),并且如果被破坏则难以调整。基于文本的格式很冗长,但往往更加健壮。如果您不确定二进制表示,文本表示往往更容易理解(除了代码页和宽/窄字符等挑战......)。

      对于 C++ XML 库,最强大的(也许也是最复杂的)似乎仍然是 Xerces library。但是您应该自己决定which library best fits your needs and skills

      【讨论】:

      • 我正在用VS2008编译.NET和c++,我不知道你的问题的答案......如果我使用XML,你能推荐一个C++库来反序列化它吗?如果我决定坚持使用二进制文件,C++ 能否理解 .NET 序列化二进制结构?
      • 如果你不确定二进制表示,你会遇到麻烦。请参阅我编辑的答案。
      【解决方案7】:

      使用 XML 序列化是最好的方法,实际上是最干净的方法。

      XmlSerializer s = new XmlSerializer( typeof( YourClassType ) );
      TextWriter w = new StreamWriter( @"c:\list.xml" );
      s.Serialize( w, yourClassListCollection );
      w.Close();
      

      【讨论】:

      • XML 序列化是最干净的,但它也是最慢的,不适合时间至关重要的地方。
      猜你喜欢
      • 1970-01-01
      • 2010-10-18
      • 2014-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多