HeapsIO / hxbit

Haxe Binary serialization and network synchronization library
155 stars 30 forks source link

I want a way to initialize hxbit at the right time in C# #47

Open kyubuns opened 4 years ago

kyubuns commented 4 years ago

I'm having trouble with the "Too late to register class" error.

https://github.com/HeapsIO/hxbit/issues/24 https://github.com/HaxeFoundation/haxe/issues/4091 https://github.com/HaxeFoundation/haxe/issues/7561

The answer is "Haxe's problem", but Haxe doesn't seem to have any plans to address it either. Could you please provide a way for all classes to be initialized when you create the Serializer for hxbit, or manually initialize hxbit?

ncannasse commented 4 years ago

Right, I guess we could add some support for this in hxbit, or another way would be a way to "preload" (and thus force statics init) some classes in C#, I'm not sure how this would work since I'm not familiar with the platform.

kyubuns commented 4 years ago

Thanks for the reply! In my opinion (I'm using C#), user calls hxbit.Serializer.init(), or initialize when the Serializer is created for the first time, it would be less likely to cause unintelligible errors than force calling static init of C# class. (I don't know Java. Sorry.)

I'm going to post the code I want to work on for your reference.

class SerializeTest {
    static function main() {
        var serializer = new hxbit.Serializer();

        var a = new Hoge(5);
        trace('a = $a');

        var serializedA = serializer.serialize(a);
        trace('serializedA = ${serializedA.toHex()}');

        var b = serializer.unserialize(serializedA, Hoge);
        trace('b = $b');

        var serializedB = serializer.serialize(b);
        trace('serializedB = ${serializedB.toHex()}');
    }
}

class Hoge implements hxbit.Serializable {
    public function new(x: Int) {
        this.x = x;
    }
    @:s public var x: Int;
}
haxe -main SerializeTest -lib hxbit --interp
SerializeTest.hx:6: a = Hoge
SerializeTest.hx:9: serializedA = 0105
SerializeTest.hx:12: b = Hoge
SerializeTest.hx:15: serializedB = 0105
haxe -main SerializeTest -lib hxbit -cs serialize_test_cs && mono ./serialize_test_cs/bin/SerializeTest.exe
haxelib run hxcs hxcs_build.txt --haxe-version 4005 --feature-level 1
Note: dmcs is deprecated, please use mcs instead!

Unhandled Exception:
System.TypeInitializationException: The type initializer for 'Hoge' threw an exception. ---> haxe.lang.HaxeException: Too late to register class
  at hxbit.Serializer.registerClass (System.Type c) [0x00014] in <c0688911d66645dda3a6efebf799a0fc>:0
  at Hoge..cctor () [0x00000] in <c0688911d66645dda3a6efebf799a0fc>:0
   --- End of inner exception stack trace ---
  at (wrapper managed-to-native) System.Object.__icall_wrapper_mono_generic_class_init(intptr)
  at SerializeTest.main () [0x00006] in <c0688911d66645dda3a6efebf799a0fc>:0
  at SerializeTest.Main () [0x00005] in <c0688911d66645dda3a6efebf799a0fc>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: The type initializer for 'Hoge' threw an exception. ---> haxe.lang.HaxeException: Too late to register class
  at hxbit.Serializer.registerClass (System.Type c) [0x00014] in <c0688911d66645dda3a6efebf799a0fc>:0
  at Hoge..cctor () [0x00000] in <c0688911d66645dda3a6efebf799a0fc>:0
   --- End of inner exception stack trace ---
  at (wrapper managed-to-native) System.Object.__icall_wrapper_mono_generic_class_init(intptr)
  at SerializeTest.main () [0x00006] in <c0688911d66645dda3a6efebf799a0fc>:0
  at SerializeTest.Main () [0x00005] in <c0688911d66645dda3a6efebf799a0fc>:0
kyubuns commented 4 years ago

I have tried to fix this problem, but this fix is not very good. This is because the initialization cost in non-C# languages has increased and the number of dependent libraries has increased. If anyone else is having trouble and is waiting for an official fix, please refer to it. https://github.com/kyubuns/hxbitmini/commit/9ce35bd2691ecfd8cbd848ce4ed54c8d4e099df0 and https://github.com/kyubuns/hxbitmini/commit/a6fd33d68b56d022cd827edbf6166d2ccd2c9666