Calling C from Fortran

Calling C from Fortran

I am trying to call a C function from Fortran.  However the first argument is coming with a bad pointer- it appears to be using the value of sBIPPath as the address, so I obviously have a pointer issue.  What is wrong with my syntax?

Here is the function in the C routine:

_declspec(dllexport) int APE(
	        char*   sBIPPath,
	        int     iCalcResAsphalt,
			double* aResinAsphalt,
			int     iResPTTuning,
			double  dResTemperature,
			double  dResPressure,
	        double* aInputMoleFractions,            
			double  dPlusFracMolWeight,
			double  dPlusFracSpecGrav,
			double* aPTRange,
			int*    aNumEnvPts,
			double* aTemperatureVL,
			double* aPressureVL,
			int*    aPtStatusVL,
                double* aTemperatureAS,
			double* aPressureAS,
			int*    aPtStatusAS,
			int*    iNumPseudoComps,
			char*   aCompNames,
			double* aOutputCompProps,
			int*    iNumErrors,
			int*    aErrorCodes)

And a Fortran calling routine:

      program FATest

      USE, INTRINSIC :: ISO_C_BINDING

      implicit none

      integer        :: ierr

      integer, parameter :: MAXERRS  = 10
      integer, parameter :: MAXCOMPS = 50
      integer, parameter :: MAXPTS   = 50
      integer, parameter :: MAXFN    = 256 

      character(256) :: sBIPPath                      ! in
      integer        :: iCalcResAsphalt               ! in
      real*8         :: aResinAsphalt(4)              ! in
      integer        :: iResPTTuning                  ! in
      real*8         :: dResTemperature               ! in
      real*8         :: dResPressure                  ! in
      real*8         :: aInputMoleFractions(12)       ! in
      real*8         :: dPlusFracMolWeight            ! in
      real*8         :: dPlusFracSpecGrav             ! in
      real*8         :: aPTRange(4)                   ! in
      integer        :: aNumEnvPts(2)                 ! in
      real*8         :: aTemperatureVL(MAXPTS)        ! out
      real*8         :: aPressureVL(MAXPTS)           ! out
      integer        :: aPtStatusVL(MAXPTS)           ! out
      real*8         :: aTemperatureAS(MAXPTS)        ! out
      real*8         :: aPressureAS(MAXPTS)           ! out
      integer        :: aPtStatusAS(MAXPTS)           ! out
      integer        :: iNumPseudoComps               ! out
      character(72)  :: aCompNames(MAXCOMPS)          ! out
      real*8         :: aOutputCompProps(2*MAXCOMPS)  ! out
      integer        :: iNumErrors                    ! out
      integer        :: aErrorCodes(MAXERRS)          ! out

!dec$ attributes C, alias : '_APE' :: APE

INTERFACE
    INTEGER FUNCTION APE(       &
                          sBIPPath,              &
                          iCalcResAsphalt,       &
                          aResinAsphalt,         &
                          iResPTTuning,          &
                          dResTemperature,       &
                          dResPressure,          &
                          aInputMoleFractions,   &
                          dPlusFracMolWeight,    &
                          dPlusFracSpecGrav,     &
                          aPTRange,              &
                          aNumEnvPts,            &
                          aTemperatureVL,        &
                          aPressureVL,           &
                          aPtStatusVL,           &
                          aTemperatureAS,        &
                          aPressureAS,           &
                          aPtStatusAS,           &
                          iNumPseudoComps,       &
                          aCompNames,            &
                          aOutputCompProps,      &
                          iNumErrors,            &
                          aErrorCodes)! BIND(C)


      character     , VALUE, INTENT(IN)  :: sBIPPath                      ! in
      integer       , VALUE, INTENT(IN)  :: iCalcResAsphalt               ! in
      real*8        , INTENT(IN)  :: aResinAsphalt(*)              ! in
      integer       , VALUE, INTENT(IN)  :: iResPTTuning                  ! in
      real*8        , VALUE, INTENT(IN)  :: dResTemperature               ! in
      real*8        , VALUE, INTENT(IN)  :: dResPressure                  ! in
      real*8        , INTENT(IN)  :: aInputMoleFractions(*)        ! in
      real*8        , VALUE, INTENT(IN)  :: dPlusFracMolWeight            ! in
      real*8        , VALUE, INTENT(IN)  :: dPlusFracSpecGrav             ! in
      real*8        , INTENT(IN)  :: aPTRange(*)                   ! in
      integer       , INTENT(IN)  :: aNumEnvPts(*)                 ! in
      real*8        , INTENT(OUT) :: aTemperatureVL(*)             ! out
      real*8        , INTENT(OUT) :: aPressureVL(*)                ! out
      integer       , INTENT(OUT) :: aPtStatusVL(*)                ! out
      real*8        , INTENT(OUT) :: aTemperatureAS(*)             ! out
      real*8        , INTENT(OUT) :: aPressureAS(*)                ! out
      integer       , INTENT(OUT) :: aPtStatusAS(*)                ! out
      integer       , INTENT(OUT) :: iNumPseudoComps               ! out
      character     , INTENT(OUT) :: aCompNames(*)                 ! out
      real*8        , INTENT(OUT) :: aOutputCompProps(*)           ! out
      integer       , INTENT(OUT) :: iNumErrors                    ! out
      integer       , INTENT(OUT) :: aErrorCodes(*)                ! out

    END FUNCTION APE
END INTERFACE

      sBIPPath                = 'd:\Tech1\'//char(0)

      ierr = APE(    sBIPPath,                    &
                     iCalcResAsphalt,             &
                     aResinAsphalt,               &
                     iResPTTuning,                &
                     dResTemperature,             &
                     dResPressure,                &
                     aInputMoleFractions,         &   
                     dPlusFracMolWeight,          &
                     dPlusFracSpecGrav,           &
                     aPTRange,                    &
                     aNumEnvPts,                  &
                     aTemperatureVL,              &
                     aPressureVL,                 &
                     aPtStatusVL,                 &
                     aTemperatureAS,              &
                     aPressureAS,                 &
                     aPtStatusAS,                 &
                     iNumPseudoComps,             &
                     aCompNames,                  &
                     aOutputCompProps,            &
                     iNumErrors,                  &
                     aErrorCodes)
      end

 

7 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Removing the "VALUE" in the line

 character     , VALUE, INTENT(IN)  :: sBIPPath                      ! in

has no effect

I changed:

 
!dec$ attributes C, alias : '_APE' :: APE

to:

 
!dec$ attributes stdcall, REFERENCE, alias : '_APE' :: APE

and it now works.

You made things worse, probably corrupting the stack.

What you want for the first argument is:

CHARACTER, DIMENSION(*), INTENT(IN) :: sBIPPath

Uncomment the BIND(C), change it to BIND(C,NAME="APE"), and remove the !DEC$ ATTRIBUTES.

As a matter of good practice, I would also recommend replacing "real*8" with "real(C_DOUBLE) and "integer" with "integer(C_INT). You will need to add IMPORT inside the interface body.

Steve - Intel Developer Support

I get a compilation error now:

FAMFTest.f90(94): error #8066: The NAME= specifier in BIND statement or in the BIND attribute specification of a type declaration statement must be a character initialization expression.   [APE]

 

oops sorry forgot my quotes...

Adrian,

See this thread - http://software.intel.com/en-us/forums/topic/505505 - and my example in Quote #5.  As shown in that example and suggested by Steve above, declaration of sBIPPath(*) would be appropriate for the first argument.

 

Leave a Comment

Please sign in to add a comment. Not a member? Join today