- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am calling a 'C' routine from Visual Fortran code but there appears to be an inconsistency. For compatibility with Fortran, the 'C' function is expecting an int* argument. At various points in the Fortran code, I call the 'C' code with constant value. Much of the time it works, the 'C' function receives a pointer to the value and everything is peachy. At one point in the code however, the 'C' function is called with the value 1 and the 'C' code receives this value as the pointer itself rather than a pointer to the value! E.G.
CALL MYFUN(5) is OK
CALL MYFUN(1) is bad!
Is this correct behavior?
On a related issue, is there a way to ensure the fortran compiler can be made to perform strict type checking on parameters when calling 'C' code? I have defined the functions using INTERFACE, but it still allows the caller to pass INT2 or INT4 parameters which messes up the C functions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The way I would do this would be to use the c-interoperability functionality and have my c prototype as
[cpp]
void myfunc(int);
[/cpp]
and my Fortran interface as
[fortran]
interface
subroutine myfunc(i) bind(c,name='myfunc')
use iso_c_binding
integer(c_int), intent(in), value :: i
end subroutine myfunc
end interface
[/fortran]
your calls should then work properly. If you need to keep the argument as int* then you should declare a variable, assign it the use it:
[fortran]
integer :: i
i = 5
call myfunc(i)
[/fortran]
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The way I would do this would be to use the c-interoperability functionality and have my c prototype as
[cpp]
void myfunc(int);
[/cpp]
and my Fortran interface as
[fortran]
interface
subroutine myfunc(i) bind(c,name='myfunc')
use iso_c_binding
integer(c_int), intent(in), value :: i
end subroutine myfunc
end interface
[/fortran]
your calls should then work properly. If you need to keep the argument as int* then you should declare a variable, assign it the use it:
[fortran]
integer :: i
i = 5
call myfunc(i)
[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
/warn:interfaces is a good option to use.
One comment on #2 if it is a stdcall C routine (like all the winapi) you can't use BIND C you need to use lots of !DEC$ Attributes ...
Dear Dr Fortran please can we have an extension to Bind C for stdcall like several other compilers do? Bizarre is it sound and extension would greatly improve portability....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Tony D.: I don't think that you have given sufficient detail to help us infer that there is anything amiss. Here is a pair of source files that do something similar to what you described. When they are compiled and run, nothing is printed out, indicating that things are as expected.
[fortran]program callc
implicit none
integer :: i,j,cfun
do i=1,2000000000
j=cfun(i)
if(j.ne.i*i)write(*,'(1x,I4,2x,i10)')i,j
end do
end program callc[/fortran]
[cpp]int CFUN(int *arg){
return (*arg)*(*arg);
}[/cpp]
Please provide source codes for an example that exhibits the problematic behavior.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the info. I tried this but it made no difference, some calls still pass the pointer and the one rogue one doesn't. It looks like there may be something else wrong with my program. I put the interface in a separate file which I have included in each FORTRAN sub that makes the call. Is this the right thing to do?
Sorry for the dumb questions but I am a C/C++ programmer and know almost zero about FORTRAN.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry guys my mistake!
The application I had built was not set up to use the current version of my FORTRAN lib, it was using an old one because the project file was set up incorrectly.
I am sure everything will work now!
Appologies
Tony
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think it unlikely the compiler version will make a difference here. If you find you still need help, we need to see the actual code - enough to build and run.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It would help if you could post code you are actually using (or at least a cut-down version of it). What did you try that made no difference (there have been three different ideas)? Are you on 32 or 64 bit? Did you try /warn:interfaces as suggested?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry for the confusion!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ah, I see. Using the wrong library file. Ok. Glad you got it straightened out.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Tony,
No hassles about asking "dumb" questions. I'm a Fortran programmer, and when I need to interface with C/C++, Im the one asking the "dumb" questions about C/C++.
If we can all help each other out, in the end, we all gain.
David

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