- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Removing the "VALUE" in the line
character , VALUE, INTENT(IN) :: sBIPPath ! in
has no effect
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I changed:
!dec$ attributes C, alias : '_APE' :: APE |
to:
!dec$ attributes stdcall, REFERENCE, alias : '_APE' :: APE |
and it now works.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
oops sorry forgot my quotes...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page