- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am building a Dll and exporting functions and subroutines as STDCALL from Fortran. There have been and still are some difficulties to have other parts in Fortran call those exported functions aswell. It works for most of the functions but two of them simply won't link.
I decorated the functions to export with !DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: <functionname>. Then I created a module to write interfaces for the exported functions, so that Fortran knows that these have STDCALL as calling convention.
The problem is with REFU and BLIND, the other functions work fine. It is unsuccessfully trying to link to _refu@36 and _blind@8.
The function MAMA is defined in the same file as BLIND, a dumpbin from the resulting obj file shows that _mama@4 and _BLIND can be found. It also shows the following linker directives, which make me wonder why the expected export for BLIND is missing:
Linker Directives ----------------- -defaultlib:ifmodintr.lib -export:_mama -export:_mama -export:_mama@4 -export:_mama@4 -defaultlib:ifconsol -defaultlib:libifcoremdd -defaultlib:libifportmd -defaultlib:libmmdd -defaultlib:MSVCRTD -defaultlib:libirc -defaultlib:svml_dispmd -defaultlib:OLDNAMES
fdllmodule.f90:
module fdllmodule
!Es folgen die Interfacedefinitionen für alle exportierten
!Funktionen, "use fdllmodule" muss ueberall stehen, wo eine
!der Funktionen auch innerhalb der FTN-DLL gerufen wird.
Interface
subroutine elsvor()
!DEC$ATTRIBUTES STDCALL :: elsvor
end subroutine elsvor
End Interface
Interface
subroutine elsend()
!DEC$ATTRIBUTES STDCALL :: elsend
end subroutine elsend
End Interface
Interface
subroutine blind(inummer,iaction)
!DEC$ATTRIBUTES STDCALL :: blind
!DEC$ATTRIBUTES Value :: inummer, iaction
integer*4 inummer, iaction
end subroutine blind
End Interface
Interface
integer*4 function get(icommon,ivar,ilaenge,ityp,irefu,lh)
!DEC$ATTRIBUTES STDCALL :: get
!DEC$ATTRIBUTES Value :: icommon,ivar,ilaenge,ityp,irefu,lh
integer*4 icommon,ivar,ilaenge,ityp,irefu
integer*4 lh
end function get
End Interface
Interface
integer*4 function iget(icommon,ivar)
!DEC$ATTRIBUTES STDCALL :: iget
!DEC$ATTRIBUTES Value :: icommon,ivar
integer*4 icommon,ivar
end function iget
End Interface
Interface
integer*4 function janein(icommon,ivar,jcommon,jvar,iverglwert,ivergltyp,irefu)
!DEC$ATTRIBUTES STDCALL :: janein
!DEC$ATTRIBUTES Value :: icommon,ivar,jcommon,jvar,iverglwert,ivergltyp,irefu
integer*4 icommon,ivar,jcommon,jvar,iverglwert,ivergltyp,irefu
end function janein
End Interface
Interface
subroutine put(icommon,ivar,ilaenge,ityp,irefu,lh)
!DEC$ATTRIBUTES STDCALL :: put
!DEC$ATTRIBUTES Value :: icommon,ivar,ilaenge,ityp,irefu
integer*4 icommon,ivar,ilaenge,ityp,irefu
integer*1 lh
end subroutine put
End Interface
Interface
subroutine iput(icommon,ivar,iwert)
!DEC$ATTRIBUTES STDCALL :: iput
!DEC$ATTRIBUTES Value :: icommon,ivar,iwert
integer*4 icommon,ivar,iwert
end subroutine iput
End Interface
Interface
subroutine refu(irefu,ivor,icommon,ivar,jcommon,jvar,ilaenge,ix,iy)
!DEC$ATTRIBUTES STDCALL :: refu
!DEC$ATTRIBUTES Value :: irefu,ivor,icommon,ivar,jcommon,jvar,ilaenge,ix,iy
integer*4 irefu,ivor,icommon,ivar,jcommon,jvar,ilaenge,ix,iy
end subroutine refu
End Interface
Interface
integer*4 function jprofu(iprofu,ipar1,ipar2,ipar3,ipar4)
!DEC$ATTRIBUTES STDCALL :: jprofu
!DEC$ATTRIBUTES Value :: iprofu,ipar1,ipar2,ipar3,ipar4
integer*4 iprofu,ipar1,ipar2,ipar3,ipar4
end function jprofu
End Interface
Interface
integer*4 function jprsys(iprsys,icommon,ivar,jcommon,jvar,ilen,jlen,lh)
!DEC$ATTRIBUTES STDCALL :: jprsys
!DEC$ATTRIBUTES Value :: iprsys,icommon,ivar,jcommon,jvar,ilen,jlen
integer*4 iprsys,icommon,ivar,jcommon,jvar,ilen,jlen
integer*1 lh
end function jprsys
End Interface
Interface
integer*4 function inex(icommon,isprung,ivar,jzaehl,irefu,jsprung)
!DEC$ATTRIBUTES STDCALL :: inex
!DEC$ATTRIBUTES Value :: icommon,isprung,jzaehl,irefu,jsprung
integer*4 icommon,isprung,ivar,jzaehl,irefu,jsprung
end function inex
End Interface
Interface
integer*4 function iluc(ivar,jkno,ilen,inhalt)
!DEC$ATTRIBUTES STDCALL :: iluc
!DEC$ATTRIBUTES Value :: ivar,jkno,ilen
integer*4 ivar,jkno,ilen,inhalt
end function iluc
End Interface
Interface
integer*4 function ilu4(ivar,jkno,ilen,inhalt,i4var,jvar)
!DEC$ATTRIBUTES STDCALL :: ilu4
!DEC$ATTRIBUTES Value :: ivar,jkno,ilen
integer*4 ivar,jkno,ilen,inhalt,i4var,jvar
end function ilu4
End Interface
Interface
subroutine elsswi(iendg,invar,memoll)
!DEC$ATTRIBUTES STDCALL :: elsswi
!DEC$ATTRIBUTES Value :: iendg,invar
integer*4 iendg,invar
integer*4 memoll(:,:)
end subroutine elsswi
End Interface
Interface
integer*4 function mama(ityp)
!DEC$ATTRIBUTES STDCALL :: mama
!DEC$ATTRIBUTES Value :: ityp
integer*4 ityp
end function mama
End Interface
Interface
double precision function wwc(iwert,linie,wert)
!DEC$ATTRIBUTES STDCALL :: wwc
!DEC$ATTRIBUTES Value :: iwert,linie,wert
integer*4 iwert,linie
double precision wert
end function wwc
End Interface
Interface
integer*4 function iiwc(iwert,linie,lh)
!DEC$ATTRIBUTES STDCALL :: iiwc
!DEC$ATTRIBUTES Value :: iwert,linie
integer*4 iwert,linie,lh
end function iiwc
End Interface
end module
pl0put.f (works):
SUBROUTINE IPUT(IC0,IV0,IWERT)
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: IPUT
use fdllmodule, ONLY : PUT, REFU
...
RETURN
END
blind.f (BLIND does not link):
SUBROUTINE BLIND(NR,MTY)
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: BLIND
use fdllmodule
...
RETURN
END
FUNCTION MAMA(IY)
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: MAMA
use cmodule
use, INTRINSIC :: ISO_C_BINDING
...
END
elspls.f (references and does not find BLIND):
SUBROUTINE ELSPLS
use fdllmodule
...
CALL BLIND(MIO(1),-1)
END
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In blind.f, could you also try adding the line
use fdllmodule, only: DELETE_ME => BLIND
in subroutine blind? Also is dummy argument lh in function iiwc correctly typed as integer*4 and not integer*1?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In blind.f, could you also try adding the line
use fdllmodule, only: DELETE_ME => BLIND
in subroutine blind? Also is dummy argument lh in function iiwc correctly typed as integer*4 and not integer*1?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
blind.f:
SUBROUTINE BLIND(NR,MTY)
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: BLIND
use fdllmodule, only: GET, IGET, JANEIN, PUT, IPUT, REFU, JPROFU,
1 JPRSYS, INEX, ELSSWI
...
END
Excluding BLIND, as you suggested, did it. Thank you very much.
As for the lh in iiwc. The answer is: I don't know. IIWC calls IWC passing LR. In IWC it is then defined as DIMENSION LH(1). There is a lot of wrong dimensions in this code. I mean using arrays as scalars happens all the time. I fixed what I ran across, while trying to figure out the linking problems.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Cool. But shouldn't ifort have issued a diagnostic?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I had them disabled, because it produces 1040 errors and i had to get the basics straight first.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page