Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29251 Обсуждение

Passing Parameters to 'C' Consistently

Tony_D_
Начинающий
1 367Просмотр.

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 баллов
1 Решение
Simon_Geard
Новый участник I
1 367Просмотр.

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]

 

Просмотреть решение в исходном сообщении

10 Ответы
Simon_Geard
Новый участник I
1 368Просмотр.

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]

 

andrew_4619
Почетный участник III
1 367Просмотр.

 /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
Почетный участник III
1 367Просмотр.

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.

Tony_D_
Начинающий
1 367Просмотр.

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_
Начинающий
1 367Просмотр.

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

Steven_L_Intel1
Сотрудник
1 367Просмотр.

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.

Simon_Geard
Новый участник I
1 367Просмотр.

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?

Steven_L_Intel1
Сотрудник
1 367Просмотр.

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

DavidWhite
Ценный участник II
1 367Просмотр.

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

Ответить