I have managed to get an Excel UDF working with a dll compiled from the c++ version of rnatrixinverse, but I suspect the code is rather clumsy. I'd be greatful for any comments on how it might be made more elegant.

Here is the VBA code:

**Code:**

Declare Function vbrmatinv Lib "d:\Users\Doug\Documents\Visual Studio 2010\Projects\Alglib2\Release\Alglib2.dll" _

(ByRef A2 As Double, ByVal M As Long) As Long

Function RMatInvdll(a As Variant) As Variant

Dim N As Long, M As Long, N2 As Long, Pivots() As Long

Dim A2() As Double, i As Long, J As Long, K As Long, Rtn As Long

If TypeName(a) = "Range" Then a = a.Value2

M = UBound(a)

N = UBound(a, 2)

' Copy 2D base 1 variant array to 1D base 0 double array

ReDim A2(0 To M * N - 1)

For i = 1 To M

For J = 1 To N

A2((i - 1) * M + J - 1) = a(i, J)

Next J

Next i

Rtn = vbrmatinv(A2(0), M)

' Copy 1D base 0 array to 2D base 1 array

For i = 1 To M

For J = 1 To N

a(i, J) = A2((i - 1) * M + J - 1)

Next J

Next i

' Assign array to function return value

RMatInvdll = a

End Function

And the c++

**Code:**

// vbmat.cpp -- Interface for VBA matrix functions.

#include "vbmat.h"

int vbrmatinv(double* av, int n)

{

int i,j,info;

matinvreport rep;

ap::real_2d_array a2;

a2.setcontent(0, n-1, 0, n-1, av);

rmatrixinverse(a2, n, info, rep);

for( i = 0; i < n; i++){

for (j=0;j<n;j++) {

av[i*n+j] = a2(i,j);

}

}

return 0 ;

}

At the VBA end the variant arrays need to be converted to a base 0 double array anyway, and the only way to do that is by looping through each element, so there is probably not much that can be done there.

I had a lot of trouble getting setcontent() to work, but I don't know why. What I ended up with is what I thought I was doing in the first place (but obviously something must be different, because now it is working :)).

For returning the array back to VBA, is it necessary to convert it to a 1D array, and if so is there a better way to do it?