Problem finding EntryPoint in generated dll

Problem finding EntryPoint in generated dll

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[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;
            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[i]);
           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...

 

AllegatoDimensione
Download bvlsF.zip82.36 KB
11 post / 0 nuovi
Ultimo contenuto
Per informazioni complete sulle ottimizzazioni del compilatore, consultare l'Avviso sull'ottimizzazione

You need to provide more info about your use case.

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[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;
            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[i]);
           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...

I'll take a look

Thank you so much Ronald. 

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[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;
            BVLS(key, m, n, a, b, bl, bu, x, w, act, zz, istate, ref loopA);

 

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

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

 

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

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

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

Accedere per lasciare un commento.