Try this in FORTRAN
:
MODULE CALCBV
INTEGER, PARAMETER :: sp = SELECTED_REAL_KIND(p=6,r=37) ! IEEE Single Precision (32-bit)
INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(p=15,r=307) ! IEEE Double Precision (64-bit)
CONTAINS
subroutine bv(key, m, n, a, b, bl, bu, x, w, act, zz, istate, loopA)
IMPLICIT NONE
!DEC$ ATTRIBUTES DLLEXPORT :: bv
!DEC$ ATTRIBUTES ALIAS:'BV' :: bv
!DEC$ ATTRIBUTES VALUE :: key, m, n
INTEGER, INTENT(IN) :: key, m, n
REAL(dp), INTENT(IN) :: a(m,n), b(m), bl(n), bu(n)
REAL(dp), INTENT(OUT) :: x(n), w(n)
REAL(dp), INTENT(IN) :: act(m,MIN(m,n)+2), zz(m)
INTEGER, INTENT(OUT) :: istate(n+1)
INTEGER, INTENT(OUT) :: loopA
! DO CALC HERE
end subroutine
END MODULE
And then call it from C#
with:
[DllImport("bv.dll", CallingConvention=CallingConvention.Cdecl, EntryPoint="BV")]
static extern void bvls(
int key, //key = 0, the subroutine solves the problem from scratch. If key > 0 the routine initializes using the user's guess about which components of x are `active'
int m,
int n,
double[] a, // m by n matrix
double[] b, // m-vector
double[] bl, //n-vector of lower bounds on the components of x.
double[] bu, //n-vector of upper bounds on the components of x.
double[] x, //unknown n-vector
//Working arrays:
double[] w, //dimension n
double[] act, //dimension m*(mm+2). mm=min(m,n).
double[] zz, //dimension m
int[] istate, //dimension n+1.
ref int loopA // number of iterations taken in the main loop, Loop A.
);
// Test code
static void BVTEST()
{
int key=0, n=2, m=3;
double[] a= { 1.0, 2.0, 3.0, 4.0, 5.0 };
double[] b= { 10.0, 20.0, 30.0 };
double[] bl= { 0.0, 1.0 };
double[] bu= { 1.0, 2.0 };
double[] x=new double[n];
double[] w=new double[n];
double[] act=new double[m*Math.Min(m, n)+2];
double[] zz=new double[m];
int[] istate=new int[n+1];
int loopA = 0;
// Call Fortran .dll
bvls(key, m, n, a, b, bl, bu, x, w, act, zz, istate, ref loopA);
}
Remember arrays are already reference types (the default) so they don't need ref
keyword. Output values need it like with loopA
, but passed by value arguments need the VALUE
attribute declaration in order to avoid passing them with ref
, like with key
, m
, n
. You might need to fix the size of act
to something bigger that it is because I am getting some memory corruption in the parameters after this.
This posting should get you going in the right direction. Remember always use Cdecl
with FORTRAN .dll and always use implicit none
declarations. Compile as x86
and Win32
and do not use AnyCPU
. Declare your exports with the ALIAS
attirbute in order to show up.