Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Creating DLL to use MATLAB from Unity issue

Discussion in 'Scripting' started by chuckfvl, May 14, 2021.

  1. chuckfvl

    chuckfvl

    Joined:
    Jul 10, 2019
    Posts:
    8
    I've been trying for quite some time to create a dll to incorporate into Unity that would allow me to call a MATLAB function without any luck.

    I created a basic function in a MATLAB .m file and created a Matlab dll based on this link:

    https://www.mathworks.com/help/matlab/matlab_external/call-matlab-function-from-c-client.html

    My DLL:

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6.  
    7. namespace Matlab2Unity
    8. {
    9.     public class Mat2Uni
    10.     {
    11.         public float[] returnVal = new float[2];
    12.         public MLApp.MLApp matlab = new MLApp.MLApp();
    13.  
    14.         public float[] testM2U1(float x, float y)
    15.         {
    16.  
    17.             // Change to the directory where the function is located
    18.             matlab.Execute(@"cd C:\Matlab2Unity");
    19.  
    20.             // Define the output
    21.             object result = null;
    22.  
    23.             // Call the MATLAB function myfunc
    24.             matlab.Feval("testFunction", 2, out result, x, y);
    25.  
    26.             // Display result
    27.             object[] res = result as object[];
    28.  
    29.             returnVal[0] = Convert.ToSingle(res[0]);
    30.             returnVal[1] = Convert.ToSingle(res[1]);
    31.  
    32.             return returnVal;
    33.  
    34.         }
    35.     }
    36. }
    It works fine if I use this DLL in a stand alone c# program. Doing it this way allows the .m file to be modified without recompiling the c# program. This was my desired outcome.

    But when I try to use the imported DLL in Unity and try to use it as so:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Matlab2Unity;
    5. using System;
    6. using System.Reflection;
    7. using UnityEngine.UI;
    8.  
    9. public class MatlabToUnity : MonoBehaviour
    10. {
    11.     Mat2Uni m2u;
    12.     float[] returnVals = new float[2];
    13.  
    14.     float x = 0.0f;
    15.     float y = 0.0f;
    16.  
    17.     public void matlabInit()
    18.     {
    19.         Debug.Log("MATLAB Initialization...");
    20.         m2u = new Mat2Uni();
    21.     }
    22.  
    23.  
    24.     public void matlabCalc()
    25.     {
    26.      
    27.         Debug.Log("MATLAB Calculation...");
    28.         for (int i = 1; i < 11; i++)
    29.         {
    30.             returnVals = m2u.testM2U1(x, y);
    31.             Debug.Log(string.Format("Matlab2Unity - X: {0:0.000} Y: {1:0.000}", returnVals[0], returnVals[1]));
    32.  
    33.             x = x + 1.0f;
    34.             y = y + 1.0f;
    35.         }
    36.         Debug.Log("MATLAB Calculation Completed.");
    37.      
    38.     }
    39. }
    After calling the matlabInit function, I get the error:

    PlatformNotSupportedException: Operation is not supported on this platform. Matlab2Unity.Mat2Uni..ctor ()

    I have tried the solution by geomorillo here:
    https://forum.unity.com/threads/use-dll-for-unity3d.132960/

    Using this method requires that you use the Matlab deploy tool and them compile everything into Unity. This does work but this removes the ability to have the .m Matlab file outside of Unity and editable.

    The reason for wanting to use Matlab and Unity is such a manner is so our math guy can prototype various filters easily with certain data that we are using Unity to visualize.

    I was running Unity 2019.4.23f1 and the Api Config Level was set to .NET 4.x

    Any help or insight is greatly appreciated, thank you.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,769
    This might be your issue. Try removing it and seeing if it works.

    I'm not sure who is going to execute this for you in a Unity context...

    I don't know what shell Matlab might expect to be present that perhaps is not present in Unity, since Unity runs as a headless app from a standard i/o point of view.
     
  3. chuckfvl

    chuckfvl

    Joined:
    Jul 10, 2019
    Posts:
    8
    I not sure is it even making it that far? I get the error when I call matlabInit() and it runs the line m2u = new Mat2Uni();

    Setting up the dll to run the Matlab application I needed to go into the Microsoft Visual Studio Project menu, select Add Reference. Select the COM tab in the Add Reference dialog box. Select the MATLAB application.

    Is there some difference I have to address since if I make a simple c# program like this and add the DLL I Created as a reference, it works fine.

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using Matlab2Unity;
    7.  
    8. namespace Matlab2Unity_Test
    9. {
    10.     class Program
    11.     {
    12.         static void Main(string[] args)
    13.         {
    14.             Mat2Uni6 m2u;
    15.  
    16.             m2u = new Mat2Uni6();
    17.  
    18.             float[] returnVal = new float[2];
    19.  
    20.             for (int x = 0; x < 20; x++)
    21.             {
    22.                 returnVal = m2u.testM2U1(x, x + 10);
    23.                 Console.WriteLine(String.Format("x: {0:0.00}", returnVal[0]));
    24.                 Console.WriteLine(String.Format("y: {0:0.00}", returnVal[1]));
    25.             }
    26.  
    27.             Console.ReadLine();
    28.         }
    29.     }
    30. }
    Thank you for your help
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,769
    I'm sorry, you're right... I misread
    testM2U1()
    as the ctor when in fact it is not. :)

    It seems it would have to be this field initializer:

    public MLApp.MLApp matlab = new MLApp.MLApp();


    Can you make that lazy / late, like a getter that caches the app it makes?
     
  5. chuckfvl

    chuckfvl

    Joined:
    Jul 10, 2019
    Posts:
    8
    So I tried to do use the Lazy Initialization but changing 3 line in the DLL to this:

    Code (CSharp):
    1. public Lazy <MLApp.MLApp> matlab = new Lazy <MLApp.MLApp>();
    2.  
    3. matlab.Value.Execute(@"cd C:\Matlab2Unity");
    4.  
    5. matlab.Value.Feval("testFunction", 2, out result, x, y);
    Not sure if I did that right but when I tried to run the test script I got the error: The lazily-initialized type does not have a public, parameterless constructor.
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,769
    No, I mean REALLY lazy:

    Code (csharp):
    1. MLApp.MLApp _matlab;
    2.  
    3. public MLApp.MLApp matlab
    4. {
    5.   get
    6.   {
    7.     if (_matlab == null)
    8.     {
    9.       _matlab = new MLApp.MLApp();
    10.     }
    11.     return _matlab;
    12.   }
    13. }
    That way it won't be made until you are well into your fully-running application state... it's just a thought, it might not make any difference at all, but at least everything ELSE should be up and running by that point.
     
  7. chuckfvl

    chuckfvl

    Joined:
    Jul 10, 2019
    Posts:
    8
    I will give it a try and let you know, but the way I was initialing it was I was calling the functions with button presses after everything seemed loaded though.
     
  8. chuckfvl

    chuckfvl

    Joined:
    Jul 10, 2019
    Posts:
    8
    Got stuck working on some other stuff but hat didn't work either.

    When you set Unity to use .NET 4.x, is there a way to know which version it's using. I don't know if it matters but I was compiling the DLL for .NET 4.6.1
     
  9. LeedsYoungO

    LeedsYoungO

    Joined:
    Feb 1, 2023
    Posts:
    1
    Did you ever solve this?