![](/img/trans.png)
[英]Serializing an IEnumerable trough WCF using Protobuf-net and Monotouch for IOS
[英]Using protobuf-net in Unity-iOS
我是一名iOS開發人員,致力於使用protobuf將Unity中生成的某些消息作為字節數組傳遞給iOS的應用程序。 我在Unity項目中使用Marc Gravell的protobuf-net( https://github.com/mgravell/protobuf-net )(我不是Unity開發人員)。
我正在按照倉庫的自述文件中的說明進行操作。 我正在從此處下載dll: https : //code.google.com/archive/p/protobuf-net/downloads
我像這樣裝飾我的班級:
using ProtoBuf;
[ProtoContract]
public class AppToPortal
{
[ProtoMember(1)]
public uint timestamp_sec { get; set; }
[ProtoMember(2)]
public Command command { get; set; }
[ProtoMember(3)]
public byte[] accessory_message { get; set; }
}
[ProtoContract]
public class PortalToApp
{
[ProtoMember(1)]
public uint timestamp_ms { get; set; }
[ProtoMember(2)]
public Event @event { get; set; }
[ProtoMember(3)]
public DeviceInfo info { get; set; }
[ProtoMember(4)]
public CommandResponse cmdRsp { get; set; }
[ProtoMember(5)]
public byte[] accessory_message { get; set; }
}
[ProtoContract]
public class Command
{
[ProtoMember(1)]
public CommandType type { get; set; }
[ProtoMember(2)]
public byte[] ota_signature { get; set; }
[ProtoContract]
public enum CommandType
{
ExampleModeOne = 1,
ExampleModeTwo = 2,
RequestDeviceInfo = 3,
TestMode = 4,
Reset = 5,
StartOTA = 6,
}
}
我的序列化器/反序列化器看起來像
public class Proto
{
public static byte[] Serialize<T>(T obj) where T : class
{
if (null == obj) return null;
try
{
using (var stream = new System.IO.MemoryStream())
{
ProtoBuf.Serializer.Serialize<T>(stream, obj);
return stream.ToArray();
}
}
catch
{
// Log error
throw;
}
}
public static T Deserialize<T>(byte[] bytes) where T : class
{
if (null == bytes) return null;
try
{
using (var stream = new System.IO.MemoryStream(bytes))
{
return ProtoBuf.Serializer.Deserialize<T>(stream);
}
}
catch
{
// Log error
throw;
}
}
}
撰寫郵件時,我正在這樣做:
// Compose message with protobuf
TimeSpan timestamp = DateTime.Now.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc));
Command command = new Command();
command.type = Command.CommandType.RequestDeviceInfo;
AppToPortal message = new AppToPortal();
message.command = command;
message.timestamp_sec = Convert.ToUInt32(timestamp.TotalSeconds);
Debug.Log(message);
// Serialize message
byte[] bytes = Proto.Serialize<AppToPortal>(message);
當我反序列化收到的字節數組時,我正在這樣做:
PortalToApp message = Proto.Deserialize<PortalToApp>(bytes);
Debug.Log("Did deserialize: " + message + " - firmware_version: " + message.info.firmware_version + " - battery_level: " + message.info.battery_level);
當我在Mac上運行此程序時,我可以序列化/反序列化任何消息,完全沒有錯誤。 但是,當我將Unity項目導出到iOS時,我在Xcode控制台中收到以下錯誤消息:
(Filename: /Users/builduser/buildslave/unity/build/Runtime/Export/Debug.bindings.h Line: 43)
NotSupportedException: /Users/builduser/buildslave/unity/build/External/il2cpp/il2cpp/libil2cpp/icalls/mscorlib/System.Reflection.Emit/DynamicMethod.cpp(19) : Unsupported internal call for IL2CPP:DynamicMethod::create_dynamic_method - System.Reflection.Emit is not supported.
at System.Reflection.Emit.DynamicMethod.CreateDynMethod () [0x00000] in <filename unknown>:0
at System.Reflection.Emit.DynamicMethod.CreateDelegate (System.Type delegateType) [0x00000] in <filename unknown>:0
at ProtoBuf.Compiler.CompilerContext.BuildSerializer (IProtoSerializer head, ProtoBuf.Meta.TypeModel model) [0x00000] in <filename unknown>:0
at ProtoBuf.Serializers.CompiledSerializer..ctor (IProtoTypeSerializer head, ProtoBuf.Meta.TypeModel model) [0x00000] in <filename unknown>:0
at ProtoBuf.Serializers.CompiledSerializer.Wrap (IProtoTypeSerializer head, ProtoBuf.Meta.TypeModel model) [0x00000] in <filename unknown>:0
at ProtoBuf.Meta.MetaType.get_Serializer () [0x00000] in <filename unknown>:0
at ProtoBuf.Meta.RuntimeTypeModel.Deserialize (Int32 key, System.Object value, ProtoBuf.ProtoReader source) [0x00000] in <filename unknown>:0
at ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream source, System.Object value, System.Type type, ProtoBuf.SerializationContext context) [0x00000] in <filename unknown>:0
at ProtoBuf.Serializer.Deserialize[T] (System.IO.Stream source) [0x00000] in <filename unknown>:0
at MCPP.Proto.Deserialize[T] (System.Byte[] bytes) [0x00000] in <filename unknown>:0
at MenuPanel.OnReceiveData (MCPP.Notification notification) [0x00000] in <filename unknown>:0
at MCPP.MCPPKit.PostNotification (MCPP.Notification aNotification) [0x00000] in <filename unknown>:0
at MCPP.IOSPlugin.didReceiveDataCallback (IntPtr ptr, Int32 length) [0x00000] in <filename unknown>:0
Rethrow as InvalidOperationException: It was not possible to prepare a serializer for: MCPP.PortalToApp
at ProtoBuf.Compiler.CompilerContext.BuildSerializer (IProtoSerializer head, ProtoBuf.Meta.TypeModel model) [0x00000] in <filename unknown>:0
at ProtoBuf.Serializers.CompiledSerializer..ctor (IProtoTypeSerializer head, ProtoBuf.Meta.TypeModel model) [0x00000] in <filename unknown>:0
at ProtoBuf.Serializers.CompiledSerializer.Wrap (IProtoTypeSerializer head, ProtoBuf.Meta.TypeModel model) [0x00000] in <filename unknown>:0
at ProtoBuf.Meta.MetaType.get_Serializer () [0x00000] in <filename unknown>:0
at ProtoBuf.Meta.RuntimeTypeModel.Deserialize (Int32 key, System.Object value, ProtoBuf.ProtoReader source) [0x00000] in <filename unknown>:0
at ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream source, System.Object value, System.Type type, ProtoBuf.SerializationContext context) [0x00000] in <filename unknown>:0
at ProtoBuf.Serializer.Deserialize[T] (System.IO.Stream source) [0x00000] in <filename unknown>:0
at MCPP.Proto.Deserialize[T] (System.Byte[] bytes) [0x00000] in <filename unknown>:0
at MenuPanel.OnReceiveData (MCPP.Notification notification) [0x00000] in <filename unknown>:0
at MCPP.MCPPKit.PostNotification (MCPP.Notification aNotification) [0x00000] in <filename unknown>:0
at MCPP.IOSPlugin.didReceiveDataCallback (IntPtr ptr, Int32 length) [0x00000] in <filename unknown>:0
MCPP.MCPPKit:PostNotification(Notification)
MCPP.IOSPlugin:didReceiveDataCallback(IntPtr, Int32)
(Filename: currently not available on il2cpp Line: -1)
NotSupportedException: /Users/builduser/buildslave/unity/build/External/il2cpp/il2cpp/libil2cpp/icalls/mscorlib/System.Reflection.Emit/DynamicMethod.cpp(24) : Unsupported internal call for IL2CPP:DynamicMethod::destroy_dynamic_method - System.Reflection.Emit is not supported.
at System.Reflection.Emit.DynamicMethod.Finalize () [0x00000] in <filename unknown>:0
UnityEngine.UnhandledExceptionHandler:PrintException(String, Exception)
UnityEngine.UnhandledExceptionHandler:HandleUnhandledException(Object, UnhandledExceptionEventArgs)
(Filename: currently not available on il2cpp Line: -1)
ProtoBuf.Serializer.Deserialize(stream)和ProtoBuf.Serializer.Serialize(stream,obj)顯然存在問題。
你知道我可能做錯了什么嗎? 任何幫助,將不勝感激。
您不能在iOS上使用Reflection.Emit,因為iOS不允許JIT編譯。
這就是為什么NotSupportedException來自... Reflection.Emit.DynamicMethod.CreateDynMethod的原因,ProtoBuf使用它在運行時生成高效的序列化代碼。
查看ProtoBuf中是否有一個選項可以禁用動態代碼生成。 否則,您可能需要使用其他序列化系統。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.