I am working at an hololens app that need some matrix operation that are not included in unity. So I am trying to build a c++ dll with some eigen based functions as explained in this tutorial
http://longqian.me/2017/02/24/eigen-in-unity/
The plugin is builded against .net framework 4.6 for 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;
}
}
I created a UWP application for pc (x64) to check if the dll works. I added an empty object to the scene with the code that uses the native plugin inside the flag !UNITY_EDITOR, and I enabled the plugin only for WSAPlayer and x86 in unity settings. I added the mcs.rsp file with the -unsafe flag for the build, and enabled unsafe code in the visual studio solution. It perfectly works.
Then I created a UWP application for hololens (x86) with same plugin settings, with a holotoolkit asset, a basic scene (using Mixed Reality Toolkit -> Configure -> Apply Mixed Reality Scene Settings) with the empty object that uses the plugin, and I got this error:
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)
Behaviour code (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
}
User contributions licensed under CC BY-SA 3.0