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

mixed prgraming - force passing argument

Muhammad_S_4
Novice
654 Views

Hi
I am working on VS2010 mixed-programing and use the Intel Compiler / VisualStudio (Intel Parallel 2015) to compile my project in VS 2010.

Console - c source:

      

    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <string.h>
    
    //#define readfile readfile_
    
    extern void readfile(char*, int*);
    
    int main()
    {
        int n, count;
        char Fname[9];
        char Name[10];
        strcpy(Fname,"AMIN.for");
        fprintf( stderr, "%s\n", Fname);
        readfile( Fname, &n , strlen (Fname));
        fprintf( stderr, "n = %d\n", n);
    //  fprintf( stderr, "%s\n", Name);
        getch();
        return 0;
    }

Subroutine - Lib fortran:

          subroutine readfile( fname1, m )
          character fname1*(*)
          integer m
          integer iounit,i
          iounit=15
          write(*,*) fname1
    c10   format (a9)
          open(iounit,file = fname1,action='read')
          read (iounit,*) m
    c20    format (i10)
          write(*,*) m
          close(iounit)
          return
          end subroutine


    
I change setting to "lower Case" (Lib1:properties->fortran->External Procedure) and my project return "n=10" and I don't have a problem, BUT in this line I have a question

   

 readfile( Fname, &n, strlen(Fname) );

I want to change that line. I want compile without strlen like:

   

readfile( Fname, &n );


When i comiple my project,it can not open and return the contents of My file(AMIN.for).
I change setting for "Lib1" in property page->fortran->External Procedure :
" Calling conversion ----> (from "default" to "STDCALL") "
and I compile it again but it can not return the contents that I want(n=10).

I want to passed force from string lenght argumet with change setting or define a little function(any trick!).
how to do it?
excuse me for bad spelling

0 Kudos
1 Solution
Muhammad_S_4
Novice
654 Views

In The Name Of God

Hi dear all

This is a best answer(by Repeat Offender)

 

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

//#define readfile readfile_

extern void readfile(char*, int*);

int main()
{
    int n, count;
    char Fname[9];
    char Name[10];

    strcpy(Fname,"AMIN.for");
    fprintf( stderr, "%s\n", Fname);

    readfile( Fname, &n);
    fprintf( stderr, "n = %d\n", n);
//  fprintf( stderr, "%s\n", Name);
    getch();
    return 0;
}

 

 

      subroutine readfile( fname1, m ) bind(C,name='readfile')
       use ISO_C_BINDING, only: C_LOC, C_F_POINTER
       implicit none
       character, target :: fname1(*)
       character(:), pointer :: fname3
       integer m
       integer iounit,i
       i = 0
       DO
         if(fname1(i+1) == achar(0)) exit
         i = i+1
       END DO
       BLOCK
         character(i), pointer :: fname2
         call C_F_POINTER(C_LOC(fname1),fname2)
         fname3 => fname2
       END BLOCK
       write(*,*) fname3
10    format (a9)
       open(newunit=iounit,file = fname3,action='read')
       read (iounit,*) m
20    format (i10)
       write(*,*) m
       close(iounit)
       return 
       end subroutine

 

 

 

 

Thanks

View solution in original post

0 Kudos
6 Replies
andrew_4619
Honored Contributor III
654 Views

You need to look at BIND(C)  read

https://software.intel.com/en-us/node/525332

and look at some other forum threads e.g. https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/392505

 

0 Kudos
FortranFan
Honored Contributor II
654 Views

app4619 wrote:

You need to look at BIND(C)  read ..

OP wants to stick to FORTRAN 77 (or some variation of it) and several readers have already tried to help him in a previous thread by him on pretty much the same topic: https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/604747.  He should find his answers in that thread.

0 Kudos
mecej4
Honored Contributor III
654 Views

I don't know what is meant by "force passing", but one has to accept that Fortran is not C and vice versa.

When you declare a subprogram argument as CHARACTER*(*), you are telling the compiler that the length of the string may be found as a (hidden argument). The C caller, however, was not told to pass that expected argument. Secondly, Fortran strings do not derive their length from the position of a null character in the string.

You can, however do something similar to the following:

      subroutine readfile( fname1, m )
      character fname1*100
      integer m
      integer iounit,i
      iounit=15
      i=index(fname1,char(0))-1
      write(*,*)'String length is ',i
      write(*,10) fname1(1:i)
 10   format ('|',a,'|')
      open(iounit,file = fname1(1:i),action='read')
      read (iounit,*) m
c20    format (i10)
      write(*,*) m
      close(iounit)
      return
      end subroutine

Note, however, that when you take seemingly capricious decisions such as:

I want to change that line. I want compile without strlen like ...

without justifying/explaining the decision, you are less likely to receive constructive responses.

0 Kudos
Muhammad_S_4
Novice
654 Views

In The Name Of God

 
Firstly Thank You for your Reply
 am working on VS2010 mixed-programing and use the Intel Compiler / VisualStudio (Intel Parallel 2015) to compile my project in VS 2010 (right-click in "soulotion explorer"->intel compiler->use visual c++).
 

I copy "AMIN.for"  to "C:\Users\Muhammad\Documents\visual studio 2010\Projects\c2\c2"

Also I change setting to "lower Case" (Lib1:properties->fortran->External Procedure) and when i compile , my project return "n=10" and I don't have a problem,BUT in this line I have a question

readfile( Fname, &n, strlen(Fname) );

I want to change that line. I want compile without strlen like:

readfile( Fname, &n );

I mean "Force passing" that was :

With this change when i compile my project , it cannot return n=10(content of AMIN.for)

What happening that can not return n=10?

How to get it by this change(without lenght)?

Is it possible that change VS2010 setting (for example : change procedure->calling conversion to STDCALL or...) to get it or define a function in c-source or any trick while i do not want change my fortran program

Thanks for your attention

0 Kudos
jimdempseyatthecove
Honored Contributor III
654 Views

mecej4's response (#4) does what you ask

The Fortran subroutine readfile accepts: fname1 which can be up to 99 characters + NULL long (change *100 to *100000 if you want longer), and a reference (address) to an integer. I caution you to specify the size of the integer on both sides (C_INT or C_INTPTR).

Jim Dempsey

 

0 Kudos
Muhammad_S_4
Novice
655 Views

In The Name Of God

Hi dear all

This is a best answer(by Repeat Offender)

 

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

//#define readfile readfile_

extern void readfile(char*, int*);

int main()
{
    int n, count;
    char Fname[9];
    char Name[10];

    strcpy(Fname,"AMIN.for");
    fprintf( stderr, "%s\n", Fname);

    readfile( Fname, &n);
    fprintf( stderr, "n = %d\n", n);
//  fprintf( stderr, "%s\n", Name);
    getch();
    return 0;
}

 

 

      subroutine readfile( fname1, m ) bind(C,name='readfile')
       use ISO_C_BINDING, only: C_LOC, C_F_POINTER
       implicit none
       character, target :: fname1(*)
       character(:), pointer :: fname3
       integer m
       integer iounit,i
       i = 0
       DO
         if(fname1(i+1) == achar(0)) exit
         i = i+1
       END DO
       BLOCK
         character(i), pointer :: fname2
         call C_F_POINTER(C_LOC(fname1),fname2)
         fname3 => fname2
       END BLOCK
       write(*,*) fname3
10    format (a9)
       open(newunit=iounit,file = fname3,action='read')
       read (iounit,*) m
20    format (i10)
       write(*,*) m
       close(iounit)
       return 
       end subroutine

 

 

 

 

Thanks

0 Kudos
Reply