Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29249 Discussions

calling C++ from Compaq Fortran 6.5.0

tcurry
Beginner
1,128 Views
I am having problems linking my C++ and Compaq Fortran. I have inserted my code below. Both files compile but they will not link together. The fortran file is calling the C function. It is really not C++ yet but I am planning to use classes in the future.

#include
#include

extern "C" {
int DIS_SPIN( unsigned int *dt );
}

int DIS_SPIN( unsigned int *dt )
{
unsigned int msecs, deltaTime;
static unsigned int prev_msecs=0;

msecs = timeGetTime();
deltaTime = msecs - prev_msecs;
while (deltaTime < (*dt))
{
msecs = timeGetTime();
deltaTime = msecs - prev_msecs;
}
return 0;
}

The fortran file that calls this function is:

SUBROUTINE DIS
IMPLICIT NONE
INTERFACE EXP
SUBROUTINE DIS_SETUP
!DEC$ ATTRIBUTES C, ALIAS:'dis_setup'::DIS_SETUP
END SUBROUTINE DIS_SETUP
FUNCTION DIS_SPIN( DT )
!DEC$ ATTRIBUTES STDCALL, ALIAS:'_DIS_SPIN@1'::DIS_SPIN
!DEC$ ATTRIBUTES REFERENCE :: DT
INTEGER*4 DT
END FUNCTION DIS_SPIN
SUBROUTINE DIS_TRANSMIT( X, Y, Z, YAW, PITCH, ROLL)
!DEC$ ATTRIBUTES C,ALIAS:'dis_transmit'::DIS_TRANSMIT
!DEC$ ATTRIBUTES REFERENCE :: X
!DEC$ ATTRIBUTES REFERENCE :: Y
!DEC$ ATTRIBUTES REFERENCE :: Z
!DEC$ ATTRIBUTES REFERENCE :: YAW
!DEC$ ATTRIBUTES REFERENCE :: PITCH
!DEC$ ATTRIBUTES REFERENCE :: ROLL
REAL*8 X, Y, Z, ROLL, PITCH, YAW
END SUBROUTINE DIS_TRANSMIT
END INTERFACE EXP

INCLUDE 'dis.inc'
C LOCAL VARIABLES
INTEGER*4 MSECS

IF (INITIAL.EQ.1) THEN

C Only setup the DIS if the DIS_DT_TRANSMIT is > 0
If( DIS_DT_TRANSMIT .GT. 0.0 ) Then
Call DIS_SETUP

C Schedule the DIS as a function of the DIS_DT_TRANSMIT
CALL SCHEDULE(45,DIS_DT_TRANSMIT,1,0,0)

ENDIF
ENDIF

C Transmit the Entity State Pdu for the current states
Call dis_transmit( RXI, RYI, RZI, HEADG, PITCH, ROLL )

IF ( DIS_REALTIME_ON .EQ. 1 ) THEN
C Spin here until the wall clock catches up
C dis_spin takes unsigned miliseconds
MSECS = 1.0/DT_MISSILE*1000
WRITE(*,*) 'MSECS=', MSECS
Call DIS_SPIN( MSECS )
ENDIF

RETURN
END


I am just concentrating of getting the DIS_SPIN function linking then I will fix the other C functions.

Thanks for your help.
Tim Curry
0 Kudos
3 Replies
Jugoslav_Dujic
Valued Contributor II
1,128 Views
1) You have calling conventions wrong -- STDCALL in Fortran, no __stdcall in C++.
2) You have the ALIAS wrong -- it can never be @1 -- it's always @number of arguments * 4.

See this recent thread.

Jugoslav
0 Kudos
tcurry
Beginner
1,128 Views
1) I took out the STDCALL and just tried the C. It still did not work. Do I have to use it? If so, where?

2) Is this because each variable is 4 bytes?

0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,128 Views
What's the error message? The attributes should be

!DEC$ ATTRIBUTES C, ALIAS: '_DIS_SPIN':: DIS_SPIN
!DEC$ ATTRIBUTES REFERENCE :: DT

There's command line tool dumpbin which you can use to inspect the linker symbols from object and dll files:

dumpbin /symbols dis_spin.obj > temp.txt will list all symbols from dis_spin.obj into file temp.txt. For dlls, the switch is /exports.

@n is appended only for __stdcall routines. It's number of bytes pushed on the stack. AFAIK only DWORDs (4-byte units) can be pushed onto stack, so the convention could have been the other ("your") way round -- but it wasn't.

Jugoslav
0 Kudos
Reply