Posted at

macOS/.NetCore2系で、utf8jsonのIL2CPP向けのCodeGeneratorを動かす

みんな大好き Utf8Json - Fast JSON Serializer for C# だけど、

IL2CPPで使うのが一手間必要で、Androidでの使用を避けてました。

とはいえ最近避けてもいられなくなったので、いい加減覚悟をきめて対応しました。

で、予想通り色々ハマったので、その際のメモ。


なお、emacs + Makefileでの完全コマンドライン開発です。



ハマりポイント1: macOS向けのCodeGeneratorは自力ビルド必須

githubで配布されてるパッケージは.netCore1時代に作られたもので、ランタイムのバージョン不整合(?)で動かない。

故に、自分でビルドする必要がある。

git clone git@github.com:neuecc/Utf8Json.git

cd Utf8Json/src/Utf8Json.UniversalCodeGenerator/
dotnet build -c Release
dotnet publish -c Release -r osx-x64
sudo mv bin/Release/netcoreapp2.0/osx-x64/publish /usr/local/Utf8Json.UniversalCodeGenerator

あとは、Makefileにこんな感じの記述を追加して、

ビルド前に呼べばOK。

CODE_GENERATOR_BIN    = /usr/local/Utf8Json.UniversalCodeGenerator/Utf8Json.UniversalCodeGenerator

CODE_GENERATOR_OUTPUT = ${PROJECT_PATH}/Assets/Scripts/Utf8JsonGenerated.cs
CODE_GENERATOR_TARGET = ${PROJECT_PATH}/${TARGET_SCRIPTS_DIR} # 複数定義する場合はカンマ区切りで列挙
CODE_GENERATOR_DEP = ${PROJECT_PATH}/${TARGET_SCRIPTS_DIR}/*.cs

${CODE_GENERATOR_OUTPUT}: ${CODE_GENERATOR_DEP}
${CODE_GENERATOR_BIN} -d "${CODE_GENERATOR_TARGET}" -o "${CODE_GENERATOR_OUTPUT}"


ハマりポイント2: 生成したコードは初期化時にセットする必要がある

忘れがちだが、Readmeにも書いてある通り適当な初期化のタイミングで、

#if ENABLE_IL2CPP

Utf8Json.Resolvers.CompositeResolver.RegisterAndSetAsDefault(
Utf8Json.Resolvers.GeneratedResolver.Instance,
Utf8Json.Resolvers.BuiltinResolver.Instance,
Utf8Json.Unity.UnityResolver.Instance
)
#endif

とか実行して、生成したリゾルバを注入してやる必要あり。


ハマりポイント3: Enumを含むシリアライズがGeneratorで生成したResolverだと例外を吐く(未解決)

デフォルトのResolverだと問題は起きないが、CodeGeneratorで生成したResolverは、Enumを含んだオブジェクトの解決に失敗するようだ。(Genertor側に手を入れれば多分対処可能)

Exception : Utf8Json.FormatterNotRegisteredException: MyClass+MyEnum is not registered in this resolver. resolver:CompositeResolver

at Utf8Json.JsonFormatterResolverExtensions.GetFormatterWithVerify[T] (Utf8Json.IJsonFormatterResolver resolver) [0x00059]

とか出る。

ちょっと嫌だけど、Enumで抱えていたところをintにして、キャスト対応することに。


参考記事