【问题标题】:Having trouble in initializing Matlab MCR when using a DLL, generated by matlab, in Unity3D在 Unity3D 中使用由 matlab 生成的 DLL 时初始化 Matlab MCR 时遇到问题
【发布时间】:2017-03-25 13:46:30
【问题描述】:

我正在 Unity3D 上开发基于 Kinect 的手势识别应用程序。我必须使用已经用 Matlab 编写的算法。因此,我决定使用 Matlab deploytool 生成一个 .Net DLL,并且我成功地做到了。然后我在一个独立的 .Net 应用程序项目(在 Visual Studio 2017 中)中测试了 DLL,它运行良好。但是,当我转向 Unity3D 时,那个 DLL 从来没有工作过......我得到的如下所示: enter image description here

System.TypeInitializationException: An exception was thrown by the type initializer for Untitled1.ADD ---> System.NotImplementedException: The requested feature is not implemented.
  at System.Security.Principal.WindowsIdentity.GetCurrent (Boolean ifImpersonating) [0x00000] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Security.Principal/WindowsIdentity.cs:166 
  at MathWorks.MATLAB.NET.Utility.MWMCR.EvaluateFunction (System.String functionName, Int32 numArgsOut, Int32 numArgsIn, MathWorks.MATLAB.NET.Arrays.MWArray[] argsIn) [0x00000] in <filename unknown>:0 
  at MathWorks.MATLAB.NET.Utility.MWMCR.EvaluateFunction (Int32 numArgsOut, System.String functionName, MathWorks.MATLAB.NET.Arrays.MWArray[] argsIn) [0x00000] in <filename unknown>:0 
  at MathWorks.MATLAB.NET.Utility.MWMCR.setBuilderUserData () [0x00000] in <filename unknown>:0 
  at MathWorks.MATLAB.NET.Utility.MWMCR..ctor (System.String componentId, System.String componentPath, System.IO.Stream embeddedCtfStream, Boolean isLibrary) [0x00000] in <filename unknown>:0 
  at Untitled1.ADD..cctor () [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at dlltest.Start () [0x00000] in E:\Unity\mPrj\Assets\dlltest.cs:40 
UnityEngine.Debug:Log(Object)
dlltest:Start() (at Assets/dlltest.cs:46)

从日志看,好像是初始化MCR失败了,但是看了Matlab生成的C#源代码后我就是不知道为什么(以前做过这个工作的人一定知道我在说什么)。 有没有人在这种工作方面经验丰富,可以向我解释发生了这种情况以及如何解决?非常感谢!

DLL 的命名空间是Untitled1(来不及给它起个名字...),DLL 中的类的名称是ADD。 以下是此过程中的相关代码(测试样例):

matlab源代码add.m:

   function y = add(n,m)

   y = n+m;

Matlab在将M文件构建成DLL时生成的C#代码太长,这里就不贴了,所以我只展示定义构造函数的代码,根据Log,Unity3D中出现错误:

static ADD()
{
  if (MWMCR.MCRAppInitialized)
  {
    Assembly assembly= Assembly.GetExecutingAssembly();

    string ctfFilePath= assembly.Location;

    int lastDelimiter= ctfFilePath.LastIndexOf(@"\");

    ctfFilePath= ctfFilePath.Remove(lastDelimiter, (ctfFilePath.Length - lastDelimiter));

    string ctfFileName = "Untitled1.ctf";

    Stream embeddedCtfStream = null;

    String[] resourceStrings = assembly.GetManifestResourceNames();

    foreach (String name in resourceStrings)
    {
      if (name.Contains(ctfFileName))
      {
        embeddedCtfStream = assembly.GetManifestResourceStream(name);
        break;
      }
    }
    mcr= new MWMCR("",
                   ctfFilePath, embeddedCtfStream, true);
  }
  else
  {
    throw new ApplicationException("MWArray assembly could not be initialized");
  }
}

在独立 .Net 应用程序中成功使用 DLL 的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MathWorks.MATLAB.NET.Utility;
using MathWorks.MATLAB.NET.Arrays;
using Untitled1;

namespace AddDllTest
{
    class Program
    {
        static void Main(string[] args)
        {

            ADD myAdd = new ADD();

            Console.WriteLine(myAdd.add((MWArray)1, (MWArray)1));

        }
    }
}

还有代码是Unity3D脚本,在Unity3D中无法使用DLL(部分cmets已被删除):

using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices; 
using RootSystem = System;
using System;
using System.Reflection;
using System.IO;
using Untitled1;
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;

public class dlltest : MonoBehaviour {

    MWArray test1 = 1;
    MWArray ref0 = 2;
    MWArray result;
    ADD myADD;

    //Use this for initializations
    void Start () {

        try
        {
            myADD = new ADD();
        }
        catch (Exception e)
        {
            Debug.Log("EXCEPTION");

            Debug.Log(e.ToString());
        }

    }

    // Update is called once per frame
    void Update () {

        result = myADD.add(test1,ref0);
        Debug.Log(result);

    }
}

【问题讨论】:

    标签: c# matlab unity3d dll


    【解决方案1】:

    看起来 MWMCR 类的静态 ctor 正在调用 Mono 类库中不受支持的方法:

    (https://github.com/Unity-Technologies/mono/blob/uniy-trunk/mcs/class/corlib/System.Security.Principal/WindowsIdentity.cs#L166)

    您的测试作为独立的 .Net 运行的原因是您可能在 CLR 上运行它。

    当您尝试运行 Unity 项目时,它使用 Mono(在大多数情况下),然后您会收到此错误。

    如果您将 Unity 项目构建为“Windows 应用商店应用程序”,它应该可以工作(因为在这种情况下,您的“游戏”将使用 CLR 运行)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-22
      • 2014-12-07
      • 1970-01-01
      相关资源
      最近更新 更多