C # Mono с протоколом protobuf-net, получающим исключение ExecutionEngineException - PullRequest
4 голосов
/ 24 февраля 2011

Сначала большое спасибо Марку Грэвеллу, автору protobuf-net http://code.google.com/p/protobuf-net/. Это действительно отличный ресурс. В любом случае, я надеюсь, что Марк или кто-то еще может помочь мне разрешить это исключение.

Я пытаюсь реализовать protobuf-сеть на мобильных устройствах (iOS и Android) с использованием игрового движка Unity3D. Unity 3.2 использует Mono 2.6, их слегка модифицированную версию mono.

Он отлично работает в редакторе, но на устройстве iOS во время выполнения происходит сбой при первом члене, который пытается сериализовать. Обратите внимание на флаг --aot-only в исключении. Я думаю, что Unity в основном строит сборку ARM с помощью функции Mono, хотя я не понимаю, что она делает под капотом.

ExecutionEngineException: Attempting to JIT compile method 'ProtoBuf.Property.Property`2<GameManagerSaveState , bool>:.ctor ()' while running with --aot-only.

at ProtoBuf.Property.PropertyBoolean`1[GameManagerSaveState]..ctor () [0x00000] in <filename unknown>:0 
at ProtoBuf.Property.PropertyFactory.CreateProperty[GameManagerSaveState] (System.Type type, ProtoBuf.DataFormat& format, MemberSerializationOptions options) [0x00000] in <filename unknown>:0 
at ProtoBuf.Property.PropertyFactory.Create[GameManagerSaveState] (System.Reflection.MemberInfo member) [0x00000] in <filename unknown>:0 
at ProtoBuf.Serializer`1[GameManagerSaveState].Build () [0x00000] in <filename unknown>:0

На IRC было предложено объявить переменные этих типов заранее, чтобы компилятору не приходилось их JIT во время выполнения. Кажется, это отличная идея, но, к сожалению, они похожи на внутренние универсальные типы и не знают, что писать в C # для объявления переменных, чтобы обмануть компилятор. Может кто-нибудь интерпретировать вышеупомянутое сообщение и сообщить мне, что компилятор должен знать заранее? Любые другие стратегии для предотвращения этого? Кстати, вот вершина класса, где он ошибается

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using ProtoBuf;

[ProtoContract]
public class GameManagerSaveState
{
    [ProtoMember(1)]
    public bool gameOver;
      // snip

Спасибо экспертам Mono и protobuf за помощь в этом! Protobuf-net, кажется, является удивительным и легким протоколом сериализации и RPC, который идеально подойдет для приложений iOS и Android, поэтому я с нетерпением жду его использования.

Ответы [ 2 ]

4 голосов
/ 24 февраля 2011

В версии v1 есть ряд проблем, которые затрудняют предварительную JIT;Версия v2, хотя и неполная, предназначена для решения многих / всех этих проблем, не в последнюю очередь путем предложения опции предварительной компиляции в dll, но даже версия только для времени выполнения должна быть намного более удобной для устройств.

Я должен также упомянуть, что порт Джона версии Java должен хорошо работать здесь, так как он больше загружен компилятором, чем загружен во время выполнения.

1 голос
/ 28 марта 2015

Используйте это перед использованием protobuf:

Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");

Кредит: https://github.com/antonholmquist/easy-serializer-unity

...