Search Unity

Question Mono build works but IL2CPP throws error.

Discussion in 'Android' started by androidevelopernerd, Dec 10, 2021.

  1. androidevelopernerd

    androidevelopernerd

    Joined:
    Dec 10, 2021
    Posts:
    2
    Hello, i'm using microsoft onnxruntime with unity. When i build for android with mono, it works great but if i change it to il2cpp, following error happens:

    Code (CSharp):
    1. MarshalDirectiveException: Cannot marshal P/Invoke call through delegate of type '.DOrtGetApi'
    2.       at System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointerInternal (System.IntPtr ptr, System.Type t) [0x00000] in <00000000000000000000000000000000>:0
    3.       at System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer (System.IntPtr ptr, System.Type t) [0x00000] in <00000000000000000000000000000000>:0
    4.       at Microsoft.ML.OnnxRuntime.NativeMethods..cctor () [0x00000] in <00000000000000000000000000000000>:0
    5.       at Microsoft.ML.OnnxRuntime.SessionOptions..ctor () [0x00000] in <00000000000000000000000000000000>:0
    6.       at Microsoft.ML.OnnxRuntime.InferenceSession..ctor (System.String modelPath) [0x00000] in <00000000000000000000000000000000>:0
    7.       at ML.Predict (UnityEngine.Texture2D framecam) [0x00000] in <00000000000000000000000000000000>:0
    8.       at CameraFeed.Update () [0x00000] in <00000000000000000000000000000000>:0
    9.     Rethrow as TypeInitializationException: The type initializer for 'Microsoft.ML.Onnx
    Any solution? Thanks.
     
  2. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,931
    I'd have to know a bit more about this type .DOrtGetApi to be provide more details. Although Mono is pretty permissive on delegate marshaling, where IL2CPP sticks to the letter of the law and tries to follow all of the marshaling rules.

    So it may be that this just happens to work on Mono when it should not work. But this also could be a bug in IL2CPP, where some marshaling case that should be handled is not handled correctly.
     
  3. bekici

    bekici

    Joined:
    Nov 1, 2018
    Posts:
    14
    Hi there,
    Did you find a solution for this issue? I've faced with the same error.
     
  4. grykrzysztof

    grykrzysztof

    Joined:
    Jan 18, 2017
    Posts:
    2
  5. skottmckay

    skottmckay

    Joined:
    Jan 31, 2022
    Posts:
    1
    I work on ONNX Runtime (ORT) (ONNX Runtime | Home) but have no knowledge of IL2CPP or Unity. I can help with more details about OrtGetApi. ORT is implemented in C++. We have C# bindings that wrap the C++ API, which is primarily available through a struct with a collection of function pointers. OrtGetApi is the call to retrieve that struct - see https://github.com/microsoft/onnxru...t.ML.OnnxRuntime/NativeMethods.shared.cs#L254

    C++ definition of the entry point: https://github.com/microsoft/onnxru...runtime/core/session/onnxruntime_c_api.h#L541

    Implementation is simply returning the address of the struct: https://github.com/microsoft/onnxru...core/session/onnxruntime_c_api.cc#L2561-L2563

    Possibly with the error message saying 'Cannot marshal P/Invoke call through delegate' it's the subsequent usage where a function pointer within that struct is called.
     
    Last edited: Jan 31, 2022
    grykrzysztof likes this.
  6. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,931
  7. grykrzysztof

    grykrzysztof

    Joined:
    Jan 18, 2017
    Posts:
    2
  8. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,931
    We've now corrected this issue internally, thanks for reporting it! As it turns out, IL2CPP was too aggressive in not allowing marshaling for delegates with by reference return types. I've lifted that restriction in the IL2CPP code, and we should get it into Unity releases soon.
     
    DrViJ, skottmckay and grykrzysztof like this.