简体   繁体   中英

JIT compile method error in Unity/Monotouch/C# setting delegate for 3rd party library

I am trying to create a chatclient for facebook for iOS in Unity/Monotouch/C#. I get the following error

ExecutionEngineException: Attempting to JIT compile method '(wrapper managed-to-native) 
System.Threading.Interlocked:CompareExchange  
(System.EventHandler`1<Matrix.EventArgs>&,System.EventHandler`1<Matrix.EventArgs>,
System.Eve ntHandler`1<Matrix.EventArgs>)' while running with --aot-only.

  at Matrix.Net.BaseSocket.add_OnConnect (System.EventHandler`1 value) [0x00000]
in <filename unknown>:0 
  at Matrix.XmppStream..ctor (StreamType type) [0x00000] in <filename unknown>:0 
  at Matrix.Xmpp.Client.XmppClient..ctor () [0x00000] in <filename unknown>:0 
  at TestFacebook.setup () [0x00000] in <filename unknown>:0 
  at TestFacebook.Start () [0x00000] in <filename unknown>:0 

(Filename:  Line: -1)

when I try to connect one of the delegates in the XMPP framework. This is the code that probably causes it:

xmppClient.OnBeforeSasl += this.xmppClient_OnBeforeSasl;

The delegate method:

public void xmppClient_OnBeforeSasl(object sender, Matrix.Xmpp.Sasl.SaslEventArgs e)
    { ... }

Have also tried to change API comparability level top .NET 2.0 without any result. Setting the xmppClient_OnBeforeSasl method as static does not help either. It works fine in Unity but crashes when running on an iOS device.

原来Matrix不支持iOS :(

You will need to remove all event usage in agsXMPP library before trying to use it in your unity project. I did use agsXMPP with some modifications and seems that it's working right.

Here are some insights for the patch (It's not really good way to go) :

Find and delete all event keywords in the library project (leave the Event class untouch, it's a different thing) then replace ( += )

xmppClient.OnBeforeSasl += this.xmppClient_OnBeforeSasl;

by ( = )

xmppClient.OnBeforeSasl = this.xmppClient_OnBeforeSasl;

as OnBeforeSasl is now a delegate, not an event and you can not register multiple handlers with this.

But anyway, it's kind of work and you can always extending it by adding addEventListener / removeEventListeners and use an array of delegate instead of only one.

I did doing that way and it's work so just try it out !

The following stack frame caused this error:

at Matrix.Net.BaseSocket.add_OnConnect (System.EventHandler`1 value) [0x00000]

The add_OnConnect method was a compiler generated method used to register an event. The way that this method is generated has been changed in newer version of Microsoft's C# compiler, which uses the generic version of Interlocked.CompareExchange for better performance and thread safety.

So check if the XMPP binaries you've got was built by some recent Visual Studio releases.

And the problem of Interlocked.CompareExchange is that the generic version of this method cannot be implemented in pure C# with acceptable performance. So the JIT has been hacked. When it reads the body of Interlocked.CompareExchange<T> , it just triggers a JIT process and generates the following IL:

ldarg.0 
ldarg.1
ldarg.2
call System.Threading.Interlocked::CompareExchange(ref Object, Object, Object)
ret

So this method will never get AOT compiled and always trigger a JIT process which will fail because iOS does not allow code generation.

Try solve the problem by rebuilding binaries which contain event registrations with MonoDevelop if the source codes are available.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM