-
Notifications
You must be signed in to change notification settings - Fork 175
Xamarin and Unity
As of MesseagePack for CLI 0.5, Xamarin and Unity (including Android and iOS) are supported.
This wiki page describe how to use MessagePack for CLI in their environment with some restrictions.
MesseagePack for CLI core API can run on Xamarin and Unity. In addition, you can use serializer (MessagePackSerializer<T>
) in their platform by generating them in advance.
iOS does NOT permit any runtime code generation from JIT to IL generation (OK, latest Xamarin supports ExpressionTree interpreter, but it is not so fast now). So, because MessagePack for CLI serialization strongly depends on runtime code generation (via System.Reflection.Emit
and/or System.Linq.Expression
), it must fail when serializer object generation. As of 0.5, MessagePack for CLI introduces new serializer generation stack which uses CodeDOM (System.CodeDom
) which spawns serializers as source code. By generating serializers source code in advance and building with them, you can get AOTed serializers.
MessagePack for CLI can use in form of a NuGet package.
- Get NuGet package and install it to Xamarin project. It contains runtime library of MessagePack for CLI. Note that it does not include any code related to runtime code generation.
Note As of 0.5.1, you can use reflection based serializers, so you does not have to do following instruction to work with MessagePack for CLI. But it is recommended to generate serializers in advance because reflection based serializers are not so fast. Note You must use generated serializers when you serialize value types (including enums) in Unity3D.
- Separate serializer generation project from application project. This project is normal desktop project and refers application library project which contains serialization targets. For example, you can use NUnit testing project.
- Get NuGet package and install latest MessagePack for CLI package to the project.
- Invoke
SerializerGenerator
API in the project. - Add generated serializers to the project as you like.
For example, you can write NUnit test code to generate serializers as follows:
// using System.Linq;
[TestFixture]
public class SerializerGenerator
{
[Test]
public void GenerateSerializers()
{
var applicationLibraryAssembly = typeof( ApplicationLibraryClass ).Assembly;
SerializerGenerator.GenerateCode(
new SerializerCodeGenerationConfiguration
{
Namespace = "Example.MessagePackSerializers",
OutputDirectory = "../../GeneratedSerializers",
SerializationMethod = SerializationMethod.Array // You tweak it to generate 'map' based serializers.
},
applicationLibraryAssembly.GetTypes().Where( type =>
/* ...you can filter types to be serialized by their namespace, custom attributes, etc... */
)
);
}
}
As you imagine, you can embed above code in MSBuild pipeline or custom build action to automate serializer code generation.
You must setup serialization context to use generated serializers as following:
- (Optional) Create custom
SerializationContext
and store it as you like. - Register serializer instances with
SerializationContext.RegisterSerializer
repeatedly. Target serialization context is custom context created above or default context viaSerializationContext.Default
. Note that you must register all serializers for object tree except some primitives or FCL(BCL) types.
- Download latest NuGet package.
- Unzip *.nupkg file and goto bin/unity3d and find MsgPack.dll file.
- Import the MsgPack.dll to your asset library.
If you don't like DLL style asset, you can import MessagePack for CLI source code to the assets as follows.
- If you have not been have Unity project, create it.
- Remember the root directory of the Assets directory.
- Get zip file from github releases page and expand it.
- Copy sources which are described in src/MsgPack.Unity3D/MsgPack.Unity3D.csproj
Run following command line to generate serializer source code. Note that you can specify --include
and --exclude
options to filter target types with regular expression toward their type full name (e.g. "System.DateTime").
- If you built target types as assembly, you can use following:
mpu.exe -s -a -n MyProduct.MsgPackSerializers -o /path-to-asset-root/MsgPackSerializers /path/to/assembly.dll
- Or (normal case) you can use following:
mpu.exe -s -n MyProduct.MsgPackSerializers -o /path-to-asset-root/MsgPackSerializers /path/to/sources/Some1.cs /path/to/sources/Some2.cs ...
When you import MsgPack as source code style instead of dll (assembly) style, you also specify --internal
option for the mpu.exe
.
- Some generics (such as
List<int>.Enumerator
) causesExecutionEngineException
. It is limitations of Mono (for iOS). MessagePack for CLI 0.6 has many workarounds for them, but issues might exist yet. - Xamarin iOS does not support dynamic code generation due to iOS limitation, so MessagePack for CLI uses reflection based implementation, they are slower than code generation implementation. You can pre-generate serializers with
SerializerGenerator
API (or you can do viampu.exe
command line tool too) to avoid this limitation.
- ALL limitations for Xamarin are also applied to Unity.
- Unity has additional limitation related to generics, so best option is avoiding generics as possible. MessagePack for CLI 0.6 has many workarounds for them, but issues may exist yet.