Passing Parameters to 'C' Consistently

Passing Parameters to 'C' Consistently

Tony D.'s picture

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.

11 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
sgeard@cad-schroer.co.uk's picture
Best Reply

The way I would do this would be to use the c-interoperability functionality and have my c prototype as

void myfunc(int);

and my Fortran interface as

interface
   subroutine myfunc(i) bind(c,name='myfunc')
      use iso_c_binding
      integer(c_int), intent(in), value :: i
   end subroutine myfunc
end interface

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:

integer :: i
i = 5
call myfunc(i)

 

app4619's picture

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

mecej4's picture

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.

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

int CFUN(int *arg){

	return (*arg)*(*arg);

	}

Please provide source codes for an example that exhibits the problematic behavior.

Tony D.'s picture

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.

Tony D.'s picture

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

Steve Lionel (Intel)'s picture

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.

Steve
sgeard@cad-schroer.co.uk's picture

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?

Tony D.'s picture
Steve Lionel (Intel)'s picture

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

Steve
David White's picture

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

Login to leave a comment.