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

Calling conventions

Martin__Paul
New Contributor I
772 Views

I have a fortran dll that exports a function whose calling convention is specified as CVF. When compiled with the 32-bit Compaq Fortran compiler (dforrt.dll runtime v.6.0.575.0) the dll call results in an unhandled exception (access violation). However, when compiled with the 32-bit Intel 10.1 compiler the call succeeds without error. I have only been able to reproduce this problem on 64 bit Vista.

I am unsure why this is the case since the calling convention is CVF (equates to stdcall) in both examples. The exe that calls the dll is built with Fortran 10.1. Any ideas?

Thanks.

0 Kudos
4 Replies
Lorri_M_Intel
Employee
772 Views
Quoting - pdm2009

I have a fortran dll that exports a function whose calling convention is specified as CVF. When compiled with the 32-bit Compaq Fortran compiler (dforrt.dll runtime v.6.0.575.0) the dll call results in an unhandled exception (access violation). However, when compiled with the 32-bit Intel 10.1 compiler the call succeeds without error. I have only been able to reproduce this problem on 64 bit Vista.

I am unsure why this is the case since the calling convention is CVF (equates to stdcall) in both examples. The exe that calls the dll is built with Fortran 10.1. Any ideas?

Thanks.

Not to be too picky, but "CVF" does not equate to "stdcall". In particular, stdcall says to pass scalar numbers by value, but with CVF convention, they are still passed by reference.

Without seeing more of an example, my first inclination is to believe you've set the calling convention for one side as STDCALL, one side as CVF, and are trying to reference a numeric scalar.

If my crystal ball has let me down on this one, please post enough code - and the commands used to build the DLL and EXE - so we have something concrete to look at.

thanks --

- Lorri

0 Kudos
Martin__Paul
New Contributor I
772 Views
Not to be too picky, but "CVF" does not equate to "stdcall". In particular, stdcall says to pass scalar numbers by value, but with CVF convention, they are still passed by reference.

Without seeing more of an example, my first inclination is to believe you've set the calling convention for one side as STDCALL, one side as CVF, and are trying to reference a numeric scalar.

If my crystal ball has let me down on this one, please post enough code - and the commands used to build the DLL and EXE - so we have something concrete to look at.

thanks --

- Lorri

Thanks for your reply, the sequence of calls is as follows: exe -> dll1 -> dll2

exe (Intel Fortran 10.1)
dll1 (Compaq Fortran)
dll2 (Intel Fortran 10.1)

All three use CVF calling convention.

The unhandled exception is reproduced on 64 bit Vista (and occasionally 32-bit) but not 32-bit XP. When dll1 is recompiled with Intel Fortran 10.1 the problem goes away.

For info, the interfaces are defined as follows:

exe

! SRCFILE1 - variable declarations

REAL, ALLOCATABLE, SAVE :: mrSWAP(:)
INTEGER, PARAMETER :: mciMaxLogChars = 1024

! mrSWAP array assignment here...

! Source file 2 - dll1 called from here

INTERFACE
SUBROUTINE DLL1FUNC(SWAP, FAIL, INFILE, OUTNAME, MSG)
CDEC$ ATTRIBUTES DLLIMPORT :: DLL1FUNC
CDEC$ ATTRIBUTES ALIAS:"DISCINT"::DLL1FUNC
REAL SWAP(*)
INTEGER FAIL
CHARACTER*(*) MSG, INFILE, OUTNAME
END SUBROUTINE DLL1FUNC
END INTERFACE

USE SRCFILE1, ONLY: mrSWAP, mciMaxLogChars
CHARACTER*(mciMaxLogChars) cOutStr
CHARACTER*256 L_MSG

! The following vars are passed in by the calling sub already assigned

INTEGER AV_FAIL
CHARACTER*(*) AC_OUTNAME, AC_INFILE

cOutStr = AC_OUTNAME
L_MSG = ' '

! Call dll1

CALL DLL1FUNC(mrSWAP, AV_FAIL, AC_INFILE, cOutStr, L_MSG)

dll1
SUBROUTINE DLL1FUNC(AV_SWAP,AV_FAIL,AC_INFILE,AV_OUTNAME,AV_MSG)
!DEC$ ATTRIBUTES DLLEXPORT :: DLL1FUNC
!DEC$ ATTRIBUTES ALIAS :"DLL1FUNC" :: DLL1FUNC
!DEC$ ATTRIBUTES DLLIMPORT :: DLL2FUNC
!DEC$ ATTRIBUTES ALIAS:"DLL2FUNC"::DLL2FUNC
IMPLICIT NONE

REAL AV_SWAP(*)
CHARACTER*(*) AC_INFILE, AV_OUTNAME, AV_MSG
INTEGER AV_FAIL

CHARACTER L_INC*256, L_OUTC*1024

INTEGER(KIND=1) L_MSGI(256)

! Various assignments here...

L_INC = AC_INFILE
L_OUTC = AV_OUTNAME

! Call dll2

CALL DLL2FUNC(AV_SWAP,AV_FAIL,L_INI,L_OUTI,L_MSGI)

Parameters have been assigned to correctly (I didn't include all code here for simplicity). It seems strange that this works when dll1 is compiled with Fortran 10.1, but not Compaq Fortran, even though the same calling convention (CVF) is used in both instances. Could this be caused by a runtime library conflict when I have an exe built with Intel Fortran calling a dll built with Compaq Fortran?

Many thanks for suggestions.

0 Kudos
Steven_L_Intel1
Employee
772 Views
I think I see the problem. Intel Fortran and CVF use a different layout for assumed-shape array descriptors, arrays with dimension (:). In general, we do not support calling CVF-compiled code from Intel Fortran, or vice-versa. It is more than just calling conventions.
0 Kudos
Martin__Paul
New Contributor I
772 Views
I think I see the problem. Intel Fortran and CVF use a different layout for assumed-shape array descriptors, arrays with dimension (:). In general, we do not support calling CVF-compiled code from Intel Fortran, or vice-versa. It is more than just calling conventions.

Right, thanks. I wonder why the problem has only shown up on 64bit? I'll proceed to use the Intel-compiled dll.

0 Kudos
Reply