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

Passing Parameters to 'C' Consistently

Tony_D_
Beginner
1,361 Views

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.

0 Kudos
1 Solution
Simon_Geard
New Contributor I
1,361 Views

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]

 

View solution in original post

0 Kudos
10 Replies
Simon_Geard
New Contributor I
1,362 Views

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]

 

0 Kudos
andrew_4619
Honored Contributor III
1,361 Views

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

0 Kudos
mecej4
Honored Contributor III
1,361 Views

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.

0 Kudos
Tony_D_
Beginner
1,361 Views

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.

0 Kudos
Tony_D_
Beginner
1,361 Views

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

0 Kudos
Steven_L_Intel1
Employee
1,361 Views

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.

0 Kudos
Simon_Geard
New Contributor I
1,361 Views

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?

0 Kudos
Steven_L_Intel1
Employee
1,361 Views

Ah, I see. Using the wrong library file. Ok. Glad you got it straightened out.

0 Kudos
DavidWhite
Valued Contributor II
1,361 Views

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

0 Kudos
Reply