在使用由matlab生成的DLL时,在Unity3D中初始化Matlab MCR时遇到了麻烦

时间:2017-03-25 13:46:30

标签: c# matlab unity3d dll

我正在开发基于Kinect的手势识别Unity3D上的应用程序。我必须使用一个用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#代码太长而无法在此处粘贴,因此我只显示定义构造函数的代码,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(某些评论已被删除):

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);

    }
}

1 个答案:

答案 0 :(得分:0)

看起来 MWMCR 类的静态ctor在Mono classlib中调用了一个不受支持的方法:

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

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

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

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