views:

103

answers:

1

The subroutine Rule_Tn in the Fortran library CUBPACK needs a parameter Integrand describing the integrated vector function. It's a

INTERFACE 
   FUNCTION Integrand(NF,X) RESULT(Value)
      USE Precision_Model
      INTEGER,                       INTENT(IN)  :: NF
      REAL(KIND=STND), DIMENSION(:), INTENT(IN)  :: X
      REAL(KIND=STND), DIMENSION(NF)             :: Value
   END FUNCTION Integrand
END INTERFACE

Since I want to call Rule_Tn from C code I need to define a function type in C exactly matching to this interface above. Thus I tried figure out how a Fortran function returns arrays. At first I supposed the following C signature

void Integrand(double* value, const int* nf, const int* x);

matches to the interface above. But far wrong! I got a segfault. And I already tested that double is the corresponding type to REAL(KIND=STND), the STND comes out of the module Precision_Model.

Now can anyone tell me what's the right signature? I'm using the GNU Fortran and C compilers.

+1  A: 

See GNU docs. It looks like you provided the arguments in a different order between Fortran and C. Try putting value last in the C prototype.

Also, you are missing bind(C) on the FUNCTION line.

Potatoswatter
That's not the point, the value of `STND` is defined in the module `Precision_Model` and I already tested that `REAL(KIND=STND)` corresponds to `double`. The question is: What's the corresponding C signature to this interface?
phlipsy
@phlipsy: you might want to change the "provided that" wording, then. Updating answer.
Potatoswatter
Ok I restated that part of my question.
phlipsy
@Potatoswatter: Of course, the source code of CUBPACK is open and I can modify it to match my needs (using the iso_c_binding module as you suggested) but at first I want to get by without any modifications in the Fortran code.
phlipsy
M. S. B.
@MSB: The way how arrays are returned by Fortran isn't standardized? In this case it really would be the best thing to use these ISO C bindings.
phlipsy
@phipsy: No, the language standard does not specify the calling conventions of Fortran. That is considered an implementation choice of the compiler vendor. If you use the ISO C Binding then the language standard requires consistency between the Fortran and C compilers of the same vendor. (Indeed, Intel ifort and gcc are consistent, even though from different authors.) And your code will be portable to the pair of compilers of a different vendor.Also, I'm not sure that the ISO C Binding supports array-valued function returns. You might need to make your glue-routine a subroutine.
M. S. B.
@MSB: You're right! I tested `BIND(C)` on a array-valued function: gfortran rejected it. Thank you for the informations!
phlipsy