-
Notifications
You must be signed in to change notification settings - Fork 15.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix to allow AOT compilers to play nicely with reflection #4559
Conversation
With this fix, Unity using IL2CPP should work with one of two approaches: - Call `FileDescriptor.ForceReflectionInitialization<T>` for every enum present in generated code (including oneof case enums) - Ensure that IL2CPP uses the same code for int and any int-based enums The former approach is likely to be simpler, unless IL2CPP changes its default behavior. We *could* potentially generate the code automatically, but that makes me slightly uncomfortable in terms of generating code that's only relevant in one specific scenario. It would be reasonably easy to write a tool (separate from protoc) to generate the code required for any specific set of assemblies, so that Unity users can include it in their application. We can always decide to change to generate it automatically later.
7d5ba37
to
b2639b2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
For me this fix did not work. With the following proto file:
And adding
to a static constructor on a class, it still raises a SIGABRT on compiled code. |
The fix is for enums - that's not an enum. Did you call ForceReflectionInitialization with all the enums in your proto? |
@leohahn: (Now I'm not on mobile...) did you get any errors logged before the crash? I seem to remember that when I tested it, I got a useful error message showing what was missing. That may only be in some environments though. What were you doing that crashed it - just printing out the string representation of a proto, or something else? I'd like to reproduce this if I can. |
Oh my bad, yeah the proto has no enums. This is a simple project that shows the error, you can see the code in https://github.com/leohahn/error-libpitaya-protobuf The code works in the editor but when compiling for iOS it crashes. Here's the stacktrace:
|
Hmm, interesting. Okay, it looks like I'll need to take a deeper look into that. To be honest, it's unlikely that I'll be able to get into that before the end of the year, but I'll see what I can do. Could you file a new issue with all these details, along with version information etc? I'll then assign it to myself and get to it when I can. |
As a workaround in the meantime, it's possible that you could add code to fix this yourself for now. Try adding this to your project: global::Google.Protobuf.WellKnownTypes.Value value = new Value();
value.ClearKind(); And see if that at least changes the error message. If it does - particularly if it changes it to another |
Hmm.... il2cpp is no longer working for me running my previous tests. It may take a little longer than expected to test this... |
Hey, thanks for the help. I'll open another issue. I'll try the workaround as well. |
The issue is here: #5422 |
@leohahn: Thanks. I've sorted out my il2cpp issue now, and I'm trying to reproduce your specific example. |
Cool, adding your workaround returns me this error:
So there is no Clear anymore |
Aha. It sounds like il2cpp may be being very aggressive with its pruning. One option would be add a use of |
Well I got a very interesting behaviour. If I make the error happen two times, the second time it works, but the first it throws the exception. |
Wow. Okay, I've no idea about that. It might be worth asking Unity support about that... |
With this fix, Unity using IL2CPP should work with one of two
approaches:
FileDescriptor.ForceReflectionInitialization<T>
for everyenum present in generated code (including oneof case enums)
enums
The former approach is likely to be simpler, unless IL2CPP changes
its default behavior. We could potentially generate the code
automatically, but that makes me slightly uncomfortable in terms of
generating code that's only relevant in one specific scenario. It
would be reasonably easy to write a tool (separate from protoc) to
generate the code required for any specific set of assemblies, so
that Unity users can include it in their application. We can always
decide to change to generate it automatically later.