Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28657 Discussions

Problem finding EntryPoint in generated dll

St
Beginner
831 Views

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...

 

0 Kudos
10 Replies
dnesteruk
Beginner
831 Views

You need to provide more info about your use case.

0 Kudos
St
Beginner
831 Views

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...

0 Kudos
Ron_Green
Moderator
831 Views

I'll take a look

0 Kudos
St
Beginner
831 Views

Thank you so much Ronald. 

0 Kudos
St
Beginner
831 Views

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);

 

0 Kudos
Ron_Green
Moderator
831 Views

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

0 Kudos
St
Beginner
831 Views

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...

 
0 Kudos
IanH
Honored Contributor II
831 Views

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.)

0 Kudos
Ron_Green
Moderator
831 Views

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

0 Kudos
Bernard
Valued Contributor I
831 Views

>>>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.

0 Kudos
Reply