Impossible to build using IL2CPP with protobuf-net.Grpc library

@JoshPeterson @Tautvydas-Zilys

CASE IN-50645

Using latest Unity 2022.3.x (also tried with latest 2021.3.x)

NOTE: Mono works without problem, it’s a IL2CCP specific issue.

I try to build with IL2CPP by referencing a gRPC library (protobuf-net.Grpc) and it is not possible to build with IL2CPP.

Library: NuGet Gallery | protobuf-net.Grpc 1.1.1

Affected method: protobuf-net.Grpc/src/protobuf-net.Grpc/Internal/MetadataContext.cs at 557a7a19e578b5a6f576572b8775fc4f9c6ff86e · protobuf-net/protobuf-net.Grpc · GitHub

The following occurs:

Thank you, this looks like a clear bug in IL2CPP. We will investigate it.

Protobuf-net V3 is incompatible with il2cpp for a few reasons. One major problem is that it implements some C# reflection features (specifically Reflection.Emit) that are fundamentally incompatible with AOT compilation - they do not play nice with each other. Mark Gravell, the author of Protobuf-net is supposedly working on V4 that will address these issues, and he knows about the Unity problem, but the timeframe is unknown. I believe PBNet is mostly a solo project for Mark, and he can only do so much.

That is good to know, thanks! With that said, I still think that this error message indicates a bug in IL2CPP, so we will continue to investigate this specific issue.

Hi, just checking, any movement here?

This IL2CPP issue was fixed quite a while ago. If you’re still seeing an compiler error please report it as a new bug.

When using protobuf-net (NuGet Gallery | protobuf-net 3.2.56) with Unity targeting Android via IL2CPP, I encounter a runtime error on the device. Might this also be related to IL2CPP?

Another forum discussion can be found here: Unsupported internal call for IL2CPP:ParameterInfo::GetTypeModifiers

An simple test:

  1. import protobuf-net;
  2. create a Packet;
  3. instantiate and serialize.
  4. produce an Android IL2CPP build and deploy it to a device.
    [ProtoContract]
    public struct GameInfoPacket
    {
        [ProtoMember(1)] public string GameName;
        [ProtoMember(2, OverwriteList = true)] public List<string> ListInfo { get; set; }
    }

    void Test()
    {
        GroupPacket packet = new GroupPacket()
        {
            GroupId = 111,
            ListPlayerInfo = new List<sting>()
            {
                "test1"
            }
        };


        using (var stream = new MemoryStream())
        {
            ProtoBuf.Serializer.Serialize(stream, packet);
            byte[] data = stream.ToArray();
            Debug.Log("DataLength:" + data.Length);
        }
     }

error info: 
Files/Unity/Hub/Editor/2022.3.62f3/Editor/Data/l/2cpp/libil2cpp/icalls/mscorlib/Syste
m.Reflection/RuntimeParameterinfo.cpp(23):Unsupportedinternal callfor
IL2CPP:RuntimeParameterlnfo:GetTypeModifiers-This icall isnot supported byi12cpp."System.Reflection.RuntimeParameterlnfo.GetCustomModifiers(System.Boolean
optional)(at<00000000000000000000000000000000>:0)
ProtoBuf.Meta.MetaType.<ResolveTupleConstructor>g__isPublicSetter|78_0
(System.Refiection.Methodinfo method)(at
<00000000000000000000000000000000>:0)
ProtoBuf.Meta.MetaType.ResolveTupleConstructor(System.Typetype,
System.Reflection.Memberlnfo&mappedMembers)(at
<00000000000000000000000000000000>:0)
ProtoBufMetaMetaTye.GetContractFamilyProtBufMetauntimeTyMod
modelSystem.Typetye,ProtoBuf.Meta.AttributeMapattributes)(at
<00000000000000000000000000000000>:0)
ProtoBuf.Meta.RuntimeTypeModel.TryGetBasicTypeSerializer(System.Typetype)
(at<00000000000000000000000000000000>:0)
ProtoBuf.Meta.RuntimeTypeModel.FindOrAddAuto(System.Typetype,
addEvenlfAutoDisabledProtoBuf.CompatibilityLevelambient)(atSystem.BooleandemandSystem.BooleanaddWithContractOnlySystem.Boolean
ProtoBufMetaRuntimeTypeModel.TryGetRepeatedProviderSystem.Tpete<00000000000000000000000000000000>:0)
ProtoBuf.CompatibilityLevel ambient)(at
<00000000000000000000000000000000>:0)
ProtoBuf.Meta.MetaType.ApplyDefaultBehaviour(System.BooleanisEnum,
ProtoBuf.ProtoMemberAttributenormalizedAtribute)(at
ProtoBuf.Meta.MetaType.ApplyDefaultBehaviourlmpl(ProtoBuf.CompatibilityLevel
<00000000000000000000000000000000>:0)
ambient)(at<00000000000000000000000000000000>:0)
ProtoBuf.Meta.MetaType.ApplyDefaultBehaviour(ProtoBuf.CompatibilityLevel
ambient)(at<00000000000000000000000000000000>:0)
ProtoBuf.Meta.RuntimeTypeModel.FindOrAddAuto(System.Typetype,
System.Booleandemand,System.BooleanaddWithContractOnlySystem.Boolean
addEvenlfAutoDisabled,ProtoBuf.CompatibilityLevelambient)(at
ProtoBufMeta.RuntimeTypeModelIsKnownTypeT](ProtoBuf.CompatibilityLevel
<00000000000000000000000000000000>:0)
ambient)(at<00000000000000000000000000000000>:0)
ProtoBuf.Meta.ValueMember.TryGetCoreSerializer
ProtoBuf.CompatibilityLevelcompatibilityLeveSystem.Tpetye(ProtoBuf.Meta.RuntimeTypeModelmodel,ProtoBuf.DataFormatdataFormat,
ProtoBufWireType&defaultWireType,System.BooleanasReference
System.BooleandynamicTypeSystemooleanoverwriteListSystemoolean
allowComplexTypes)(at<00000000000000000000000000o>:0)ProtoBuf.Meta.ValueMember.BuildSerializerO(at
<00000000000000000000000000000000>:0)
<00000000000000000000000000000000>:0)ProtoBuf.Meta.ValueMember.get_SerializerO(at
ProtoBufMetaMTBuilrializ(a<00000000000000000000000000000000>:0)
ProtoBuf.Meta.MetaType.geSerlalizerO(at<00000000000000000000000000000000>:0)
ProtoBuf.Meta.RuntimeTypeModel.<GetServicesSloMow>g_GetServiceslmpl/88_0
(ProtoBuf.MetauntimeTypeModelmodel,System.Typetype
ProtoBuf.CompatibilityLevelambient)(at
<00000000000000000000000000000000>:0)
ProtoBuf.Meta.RuntimeTypeModel.GetServicesSlow(System.Typetype
ProtoBuf.CompatibilityLevelambient)(at
<00000000000000000000000000000000>:0)
ProtoBufMetaRuntimeTypeModelGetSerializerTO(at
<00000000000000000000000000000000>:0)
ProtoBufMeta.TypeModelSerializemp(ProtoBuf.ProtWriter+State&state
value)(at<00000000000000000000000000000000>:0)
ProtoBuf.Serializer.Serialize[T](System.IO.Streamdestination,Tinstance,