Я работаю в приложении 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
}