Включить нативный плагин в приложение hololens - PullRequest
0 голосов
/ 07 декабря 2018

Я работаю в приложении hololens, которому нужна матричная операция, которая не входит в единство.Поэтому я пытаюсь создать DLL на языке c ++ с некоторыми собственными функциями, как описано в этом уроке

http://longqian.me/2017/02/24/eigen-in-unity/

Плагин построен на основе .net Framework 4.6 для x86

#include "stdafx.h"
#define EXPORT_API __declspec(dllexport)
#include <Eigen/Dense>
using namespace Eigen;
extern "C" {
    EXPORT_API float* solveSystem(float * A, float * b, const int nrows, const int ncols) {
        MatrixXd coefficientMatrix = MatrixXd::Matrix(nrows, ncols);
        VectorXd rightHandSideVector(ncols);
        VectorXd x;
        float *s = new float[nrows + 1];

        for (int j = 0; j < ncols; j++)
            for (int i = 0; i < nrows; i++)
                coefficientMatrix(i, j) = A[j*nrows + i];

        for (int i = 0; i < nrows; i++)
            rightHandSideVector(i) = b[i];
        x = coefficientMatrix.bdcSvd(ComputeThinU | ComputeThinV).solve(rightHandSideVector);
        for (int i = 0; i < ncols; i++)
            s[i] = x(i);
        return s;
    }

    EXPORT_API int releaseMemory(int* pArray)
    {
        delete[] pArray;
        return 0;
    }
}

Я создал приложение UWP для ПК (x64), чтобы проверить, работает ли dll.Я добавил пустой объект в сцену с кодом, который использует собственный плагин внутри флага! UNITY_EDITOR, и я включил плагин только для WSAPlayer и x86 в настройках Unity.Я добавил файл mcs.rsp с флагом -unsafe для сборки и включил небезопасный код в решении Visual Studio.Это прекрасно работает.

Затем я создал приложение UWP для hololens (x86) с такими же настройками плагина, с активом holotoolkit, базовой сценой (используя Mixed Reality Toolkit -> Configure -> Apply Mixed Reality Scene Settings)с пустым объектом, который использует плагин, и я получил эту ошибку:

Exception thrown: 'System.DllNotFoundException' in Assembly-CSharp.dll
An exception of type 'System.DllNotFoundException' occurred in Assembly-CSharp.dll but was not handled in user code
Unable to load DLL 'Eigen': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

Код поведения (EigenInterface.cs):

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;

public class EigenInterface : MonoBehaviour {
    #if !UNITY_EDITOR
    public const int MAXSIZE = 100;
    public const String path = "";

    [DllImport("Eigen")]
    unsafe static extern void releaseMemory(float* p);

    [DllImport("Eigen")]
    unsafe static extern float* solveSystem(float* A, float* b, int nrows, int ncols);

    public unsafe struct LinearSystem
    {
        public fixed float A[MAXSIZE * MAXSIZE];
        public fixed float b[MAXSIZE];
        public int nrows;
        public int ncols;

        public unsafe float[] Result
        {
            get
            {
                fixed (float* ptrA = A, ptrB = b)
                {
                    float* ptrX = solveSystem(ptrA, ptrB, nrows, ncols);
                    float[] Xarray = new float[ncols];

                    Marshal.Copy((IntPtr)ptrX, Xarray, 0, nrows);

                    releaseMemory(ptrX);
                    return Xarray;
                }
            }
        }
    }

    public unsafe static float[] SolveSystem(float[] A, float[] b)
    {
        int ncols = b.Length, nrows = A.Length / ncols;
        LinearSystem system;
        for (int i = 0; i < (nrows * ncols); i++)
            system.A[i] = A[i];
        for (int i = 0; i < ncols; i++)
            system.b[i] = b[i];
        system.nrows = nrows;
        system.ncols = ncols;

        return system.Result;
    }

    void Start()
    {
        float[] A = { 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2 };
        float[] b = { 1, 1, 1, 1, 1 };
        float[] x = SolveSystem(A, b);

        string solution = "";
        foreach (float el in x)
            solution += el.ToString() + " ";
        Debug.Log("Solution: " + solution);
    }
    #endif
}
...