- 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