我有一个protobuf对象,我从一个C#应用程序(使用clrZmq)发送到本地机器上的C ++服务(使用zmq C ++绑定)(用于测试)。我尝试使用以下
从C#发送我的对象Taurus.Odds odds = Util.GetFakeOdds();
using (var context = ZmqContext.Create())
using (var socket = context.CreateSocket(SocketType.REQ))
{
byte[] buffer = null;
socket.Connect(TARGET); // TARGET = "tcp://127.0.0.1:6500"
Taurus.FeedMux mux = new Taurus.FeedMux();
mux.type = Taurus.FeedMux.Type.ODDS;
mux.odds = odds;
SendStatus status = socket.Send(mux.ToByteArray());
if (status == SendStatus.Sent)
{
int i;
byte[] arr = socket.Receive(buffer, SocketFlags.None, out i);
Taurus.Bet bet = buffer.ToObject<Taurus.Bet>();
}
...
}
我通过扩展方法将Taurus.Odds
对象序列化到byte[]
的位置
public static byte[] ToByteArray(this object o)
{
if(o == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, o);
return ms.ToArray();
}
}
我在C ++应用程序中看到代码收到消息,但C ++ ZMQ类无法正确反序列化。我有一些Java代码以相同的方式发送到C ++代码而没有问题。我的问题是,我是否正确地通过ZMQ在上面发送我的对象,如果不是我做错了什么?
感谢您的时间。
答案 0 :(得分:1)
这是您的错误:
我通过扩展方法
将Taurus.Odds
对象序列化为byte[]
... BinaryFormatter bf = new BinaryFormatter(); ...
您似乎不知道BinaryFormatter
是什么。 与ProtoBuf 无关。 docs说出以下内容:
序列化和反序列化对象或连接对象的整个图表,以二进制格式。
此二进制格式是特定于.NET的实现细节。由于版本控制支持不佳,它的非常严格。它主要用于.NET远程处理日,今天使用它通常被认为是一个坏主意,因为有更好的序列化器。
正如您所看到的,您的C ++应用程序无法读取它,因为它不是protobuf格式。
所以抛弃这个方法并用一些适当的protobuf序列化代码替换它,如in the protobuf-net docs所述。您需要在对象中添加[ProtoContract]
和[ProtoMember]
属性。然后你可以这样写:
public static byte[] ToByteArray<T>(this T o)
{
if (o == null)
return null;
using (MemoryStream ms = new MemoryStream())
{
ProtoBuf.Serializer.Serialize(ms, o);
return ms.ToArray();
}
}