- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In The Name Of God
I copy "AMIN.for" to "C:\Users\Muhammad\Documents\
Also I change setting to "lower Case" (Lib1:properties->fortran->
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page