- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is Fortran code from Stark, P.B., and R.L. Parker I build it on Visual Studio 2010 uing Fortran Compiler (Compóser XE 2011)
Original code is Fortran
subroutine bvls(key, m, n, a, b, bl, bu, x, w, act, zz, istate, loopA) implicit double precision (a-h, o-z) !DEC$ ATTRIBUTES DLLEXPORT :: bvls dimension a(m,n), b(m), x(n), bl(n), bu(n) ! dimension w(n), act(m,min(m,n)+2), zz(m), istate(n+1) dimension w(n), act(m,m+2), zz(m), istate(n+1)
C# code (I am not sure about [In,Out] and ref variables)
[DllImport("bvlsF.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 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. [In, Out] double[] x, //unknown n-vector //Working arrays: [In, Out] double[] w, //dimension n double[] act, //dimension m*(mm+2). mm=min(m,n). double[] zz, //dimension m [In, Out] int[] istate, //dimension n+1. ref int loopA // number of iterations taken in the main loop, Loop A. );
To test dll I do:
static void BVTEST() { int key = 0, n = 2, m = 3; double[] a = { 19.0, 27.0, 33.0, 42.0, 51.0 }; double[] b = { 12.0, 27.0, 30.0 }; double[] bl = { 0.1, 0.2 }; double[] bu = { 0.9, 0.9 }; double[] x = new double; double[] w = new double ; double[] act = new double[m * (Math.Min(m, n) + 2)]; double[] zz = new double ; int[] istate = new int[n + 1]; int loopA = 0; bvls(key, m, n, a, b, bl, bu, x, w, act, zz, istate, ref loopA); for (int i = 0; i < x.Length; i++) Console.WriteLine(" " + x); Console.WriteLine(loopA); }
However I get:
System.EntryPointNotFoundException: Can not find entrypoint 'bvls' on file 'bvlsF.dll'.
on bvlsCs.Program.bvls(Int32 key, Int32 m, Int32 n, Double[] a, Double[] b, D
ouble[] bl, Double[] bu, Double[] x, Double[] w, Double[] act, Double[] zz, Int3
2[] istate, Int32& loopA)
I do not understand why is happening, so I tested with sample code I found on forum and it works:
fortran
subroutine Arr_Sub (var,row,col) !DEC$ ATTRIBUTES DLLEXPORT :: Arr_Sub integer :: row,col real var(col,row) integer :: i, j write(*,*) "Array var received from C# as array is" write(*,*) var ! do something to change the value of var end subroutine
c#
[DllImport("bvlsF.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern void ARR_SUB([In,Out] float[,] fArr, ref int row, ref int col);
and
float[,] fArr = new float[3, 4] { { 1, 23, 3, 4 }, { 1, 3, 20, 5 }, { 1, 23, 3, 6 } }; int row = 3; int col = 4; ARR_SUB(fArr, ref row, ref col);
Could you please help me execute that fortran code in c#?, I attach visual studio with fortran code...
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You need to provide more info about your use case.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is Fortran code from Stark, P.B., and R.L. Parker I build it on Visual Studio 2010 uing Fortran Compiler (Compóser XE 2011)
Original code is Fortran
subroutine bvls(key, m, n, a, b, bl, bu, x, w, act, zz, istate, loopA) implicit double precision (a-h, o-z) !DEC$ ATTRIBUTES DLLEXPORT :: bvls dimension a(m,n), b(m), x(n), bl(n), bu(n) ! dimension w(n), act(m,min(m,n)+2), zz(m), istate(n+1) dimension w(n), act(m,m+2), zz(m), istate(n+1)
C# code (I am not sure about [In,Out] and ref variables)
[DllImport("bvlsF.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 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. [In, Out] double[] x, //unknown n-vector //Working arrays: [In, Out] double[] w, //dimension n double[] act, //dimension m*(mm+2). mm=min(m,n). double[] zz, //dimension m [In, Out] int[] istate, //dimension n+1. ref int loopA // number of iterations taken in the main loop, Loop A. );
To test dll I do:
static void BVTEST() { int key = 0, n = 2, m = 3; double[] a = { 19.0, 27.0, 33.0, 42.0, 51.0 }; double[] b = { 12.0, 27.0, 30.0 }; double[] bl = { 0.1, 0.2 }; double[] bu = { 0.9, 0.9 }; double[] x = new double; double[] w = new double ; double[] act = new double[m * (Math.Min(m, n) + 2)]; double[] zz = new double ; int[] istate = new int[n + 1]; int loopA = 0; bvls(key, m, n, a, b, bl, bu, x, w, act, zz, istate, ref loopA); for (int i = 0; i < x.Length; i++) Console.WriteLine(" " + x); Console.WriteLine(loopA); }
However I get:
System.EntryPointNotFoundException: Can not find entrypoint 'bvls' on file 'bvlsF.dll'. on bvlsCs.Program.bvls(Int32 key, Int32 m, Int32 n, Double[] a, Double[] b, D ouble[] bl, Double[] bu, Double[] x, Double[] w, Double[] act, Double[] zz, Int3 2[] istate, Int32& loopA)
I do not understand why is happening, so I tested with sample code I found on forum and it works:
fortran
subroutine Arr_Sub (var,row,col) !DEC$ ATTRIBUTES DLLEXPORT :: Arr_Sub integer :: row,col real var(col,row) integer :: i, j write(*,*) "Array var received from C# as array is" write(*,*) var ! do something to change the value of var end subroutine
c#
[DllImport("bvlsF.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern void ARR_SUB([In,Out] float[,] fArr, ref int row, ref int col);
and
float[,] fArr = new float[3, 4] { { 1, 23, 3, 4 }, { 1, 3, 20, 5 }, { 1, 23, 3, 6 } }; int row = 3; int col = 4; ARR_SUB(fArr, ref row, ref col);
Could you please help me execute that fortran code in c#?, I attach visual studio with fortran code...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'll take a look
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you so much Ronald.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have changed the c# code like (changed bvls to BVLS):
[DllImport("bvlsF.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 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. [In, Out] double[] x, //unknown n-vector //Working arrays: [In, Out] double[] w, //dimension n double[] act, //dimension m*(mm+2). mm=min(m,n). double[] zz, //dimension m [In, Out] int[] istate, //dimension n+1. ref int loopA // number of iterations taken in the main loop, Loop A. );
And now it seems it finds the routine, however I am getting other error:
Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at bvlsCs.Program.BVLS(Int32 key, Int32 m, Int32 n, Double[] a, Double[] b, Double[] bl, Double[] bu, Double[] x, Double[] w, Double[] act, Double[] zz, Int32[] istate, Int32& loopA)
I am doing:
int key = 0, n = 2, m = 3; double[] a = { 19.0, 27.0, 33.0, 42.0, 51.0 }; double[] b = { 12.0, 27.0, 30.0 }; double[] bl = { 0.1, 0.2 }; double[] bu = { 0.9, 0.9 }; double[] x = new double; double[] w = new double ; double[] act = new double[m * (Math.Min(m, n) + 2)]; double[] zz = new double ; int[] istate = new int[n + 1]; int loopA = 0; BVLS(key, m, n, a, b, bl, bu, x, w, act, zz, istate, ref loopA);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You only sent the Fortran so I don't have the full solution. Still I think I can answer this.
Fortran default is to create symbols in UPPER CASE unless you tell it otherwise. notice the sample, in C# you reference ARR_SUB in uppercase, not 'Arr_Sub' as it appears in the Fortran. The compiler creates the external symbol for bvls as "BVLS" not "bvls".
So if you reference BVLS this should work. Alternatively, you can add another directive to the fortran to force lowercase:
!DIR$ ATTRIBUTES ALIAS:'blvs' :: blvs
!DIR$ ATTRIBUTES DLLEXPORT :: blvs
I think you can combine the 2 directives thusly
!dir$ attributes dllexport, alias:'blvs' :: blvs
let me know if this works.
ron
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Ron, this works as expected, however As explained in a previous comment now I am getting other error
Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at bvlsCs.Program.BVLS(Int32 key, Int32 m, Int32 n, Double[] a, Double[] b, Double[] bl, Double[] bu, Double[] x, Double[] w, Double[] act, Double[] zz, Int32[] istate, Int32& loopA)
Also, do you think parameters are well defined on dllimport on c# code?
It seems there is memory violation somewhere but i can not find where...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To rely a little less on directives (you still need to mark the procedure for export) you could alternatively add the BIND(C, NAME='bvls') suffix to the subroutine statement.
(If you are also calling the bvls procedure from Fortran, you then also need an explicit interface.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't know C#, but from the working sample it appears all arrays should be passed [IN,OUT] and all scalars by 'ref'
[DllImport("bvlsF.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] static extern void BVLS( ref 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' ref int m, ref int n, [In, Out] double[] a, // m by n matrix [In, Out] double[] b, // m-vector [In, Out] double[] bl, //n-vector of lower bounds on the components of x. [In, Out] double[] bu, //n-vector of upper bounds on the components of x. [In, Out] double[] x, //unknown n-vector //Working arrays: [In, Out] double[] w, //dimension n [In, Out] double[] act, //dimension m*(mm+2). mm=min(m,n). [In, Out] double[] zz, //dimension m [In, Out] int[] istate, //dimension n+1. ref int loopA // number of iterations taken in the main loop, Loop A. );
If this doesn't work, I'd like you to send me the C# source to work with. I have the Fortran project (unless this has changed)
ron
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>>System.EntryPointNotFoundException: Can not find entrypoint 'bvls' on file 'bvlsF.dll'.
on bvlsCs.Program.bvls(Int32 key, Int32 m, Int32 n, Double[] a, Double[] b, D
ouble[] bl, Double[] bu, Double[] x, Double[] w, Double[] act, Double[] zz, Int3
2[] istate, Int32& loopA>>>
It is quite confusing message.I suppose that error here is related to exported bvls function from bvlsF.dll..You can check bvlsF.dll with Dependency Walker or with dumpbin.
![](/skins/images/B7BA37F9CE4B52FF7CAE1FB0388839C8/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page