- Home /
Issue with IL2CPP where Default Constructor is possibly stripped from assembly
Apologies if this is not the right place to ask about this error. I've been at this for 4-5 days.
Specs: protobuf-net 3.0.73 integrated into a Unity 2019.4.6f1 project that targets .NET Standard 2.0 when building for Xbox console with IL2CPP set to Low Stripping. Exact log: "MissingMthodException: Default constructor not found for type ProtoBuf.Internal.PrimaryTypeProvider"
The project built in Editor works exactly as intended and that's why I think it's the IL2CPP stripping. Error is reported when attempting to assign a new data field of ProtoTest. Might be important to note that the ProtoTest class is a C# Library DLL coded and programmed outside of the Unity environment, as required per ProtoBuf Custom serialization. (To my knowledge). I then built it and ported it into Unity Plugins folder along with the matching Serializer.
ProtoTest saveFile = new ProtoTest(); // This is the call made where the code will fail
----- // Decorated class
[ProtoContract()]
public class ProtoTest
{
[ProtoMember(1)]
public string testString;
[ProtoMember(2)]
public int testint;
[ProtoMember(3)]
public int testBool;
[ProtoMember(4)]
public int[] testFixedIntArray;
[ProtoMember(5)]
public List<int> testList = new List<int>();
[ProtoMember(6)]
public Dictionary<int, string> testDictionary = new Dictionary<int, string>();
// This is the constructor that is being stripped (to my knowledge)
public ProtoTest() { }
}
I suspect that some off the protobuf files are being stripped during the build, I don't have a lot of experience with handling this. However I attempted to omit the protobuf namespace from stripping by writing a Linker referencing the namespaces used to create all the protobuf data I know of.
Might be important to note that the ProtoTest class is a C# Library DLL coded and programmed outside of the Unity environment, as required per ProtoBuf Custom serialization. (To my knowledge).
Attempt 1
<linker>
<assembly fullname="ProtoBuf">
<namespace fullname="ProtoBuf.Internal.PrimaryTypeProvider" preserve="all"/>
</assembly>
</linker>
Attempt 2
<linker>
<assembly fullname="ProtoSave" preserve="all"/>
<assembly fullname="ProtoBuf" preserve="all"/>
<assembly fullname="ProtoBuf.Internal" preserve="all"/>
<assembly fullname="ProtoBuf.Meta" preserve="all"/>
</linker>
Attempt 3
<linker>
<namespace fullname="ProtoSave" preserve="all"/>
<namespace fullname="ProtoBuf" preserve="all"/>
<namespace fullname="ProtoBuf.Internal" preserve="all"/>
<namespace fullname="ProtoBuf.Meta" preserve="all"/>
<namespace fullname="ProtoBuf.Serializers" preserve="all"/>
<namespace fullname="DataSerializer" preserve="all"/>
</linker>
Answer by JoshPeterson · Dec 11, 2020 at 12:05 PM
I would recommend reviewing the documentation about the linker if you have not done so: https://docs.unity3d.com/Manual/ManagedCodeStripping.html.
I think the question is, which assembly does the ProtoTest
type live in? Once you know that, you can start by preserving that entire assemly:
<linker>
<assembly fullname="ProtoTestAssembly" preserve="all"/>
</linker>
This is probably not a good long term solution, but it will help isolate the issue. Once you know this, then you can more specific preserve only the types in that assembly that you need.
I will look into this, but that being said the ProtoTest class lives in the ProtoSave assembly. And in my second attempt at the linker, I did include that assembly.
$$anonymous$$issing$$anonymous$$ethodException: Default constructor not found for type ProtoBuf.Internal.PrimaryTypeProvider at System.RuntimeType.CreateInstance$$anonymous$$ono (System.Boolean nonPublic) [0x00000] in :0 at System.Activator.CreateInstance (System.Type type, System.Boolean nonPublic) [0x00000] in :0 at ProtoBuf.Serializers.SerializerCache`1[TProvider]..cctor () [0x00000] in :0 at ProtoBuf.Internal.TypeHelper`1[T]..cctor () [0x00000] in :0 at ProtoBuf.$$anonymous$$eta.Type$$anonymous$$odel.SerializeImpl[T] (ProtoBuf.ProtoWriter+State& state, T value) [0x00000] in :0 at ProtoBuf.$$anonymous$$eta.Type$$anonymous$$odel.Serialize[T] (System.IO.Stream dest, T value, System.Object userState) [0x00000] in :0 at PlatformDeskTop.SaveFileAsProto[T] (CPlatformDataFile _FileData) [0x00000] in :0 at System.EventHandler`1[TEventArgs].Invoke (System.Object sender, TEventArgs e) [0x00000] in :0 at UI$$anonymous$$enuButtonGroup.Update () [0x00000] in :0 Rethrow as TypeInitializationException: The type initializer for 'ProtoBuf.Serializers.SerializerCache' threw an exception. at ProtoBuf.Internal.TypeHelper`1[T]..cctor () [0x00000] in :0 at ProtoBuf.$$anonymous$$eta.Type$$anonymous$$odel.SerializeImpl[T] (ProtoBuf.ProtoWriter+State& state, T value) [0x00000] in :0 at ProtoBuf.$$anonymous$$eta.Type$$anonymous$$odel.Serialize[T] (System.IO.Stream dest, T value, System.Object userState) [0x00000] in :0 at PlatformDeskTop.SaveFileAsProto[T] (CPlatformDataFile _FileData) [0x00000] in :0 at System.EventHandler`1[TEventArgs].Invoke (System.Object sender, TEventArgs e) [0x00000] in :0 at UI$$anonymous$$enuButtonGroup.Update () [0x00000] in :0 Rethrow as TypeInitializationException: The type initializer for 'ProtoBuf.Internal.TypeHelper' threw an exception. at ProtoBuf.$$anonymous$$eta.Type$$anonymous$$odel.SerializeImpl[T] (ProtoBuf.ProtoWriter+State& state, T value) [0x00000] in :0 at ProtoBuf.$$anonymous$$eta.Type$$anonymous$$odel.Serialize[T] (System.IO.Stream dest, T value, System.Object userState) [0x00000] in :0 at PlatformDeskTop.SaveFileAsProto[T] (CPlatformDataFile _FileData) [0x00000] in :0 at System.EventHandler`1[TEventArgs].Invoke (System.Object sender, TEventArgs e) [0x00000] in :0 at UI$$anonymous$$enuButtonGroup.Update () [0x00000] in :0
It looks like this error is for a different type now: ProtoBuf.Internal.PrimaryTypeProvider
Your answer
Follow this Question
Related Questions
Linker error - Unity on iOS/React Native project 1 Answer
DataContract serialization with IL2CPP 1 Answer
Cloud Build warning: Can't find custom attr constructor image 2 Answers
No Line numbers in stack trace for debug android build using IL2CPP 1 Answer
Did logic for selecting assemblies for UnusedByteCodeStripper2 and il2cpp change? 1 Answer