- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a C library that has been set up with a -iface:cvf type interface. I.e. if I compile the FORTRAN with -iface:cvf then it link correctly. Unfortunately in the FORTRAN I have calls to other C and FORTRAN librariesthat do not use the cvf calling convention.
From what I have read I need to set up an interface block with a CFV type compiler directive. I.e. call some routines with thecvf type convention. Something like
interface
subroutine gm_start_cad(igeofile,lugeo_in,isemod,split2)
c CDEC$ ATTRIBUTES CVF :: gm_start_cad
character*80 igeofile
integer lugeo_in, isemod
logical split2
end subroutine gm_start_cad
end interface
Unfortunately the compiler does not recognise the CVF option. I have tried various other combinations (DECORATE, ALIAS, STDCALL) but cannot get it to link. Does anyone know what set of directives I need to mimick the cvf convention? Or is there another way of doing this?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
!DEC$ ATTRIBUTES STDCALL,REFERENCE,DECORATE.,ALIAS:"GM_START_CAD" :: gm_start_cad
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the response - trying that directive I get
libgeolib.a(gm_util.o) : error LNK2019: unresolved external symbol _GM_START_CAD@16 referenced in function _GM_START
The argument list to gm_start_cad is (character,int, int, logical) If I nm -a the library is has an entry for _GM_START_CAD@20which is what I would expect with the extra int for the length of the string. It looks like the directives are not adding the length of the string to the argument list. Is there any way around this (apart from adding the argument myself)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I used -extend_source for the compiler option
Next question - do I need to add the string length after the character variable in the argument list? see below, If I do this the code crashes in calling the c routine.
subroutine gm_start_cad(igeofile,lugeo_in,isemod,split2)
character*(*) igeofile
logical split2
interface
subroutine gm_start_cad1(igeofile,li,lugeo_in,isemod,split2)
CDEC$ ATTRIBUTES DECORATE,STDCALL,MIXED_STR_LEN_ARG,ALIAS:'GM_START_CAD' :: gm_start_cad1
character*80 igeofile
integer lugeo_in, isemod
logical split2
end subroutine gm_start_cad1
end interface
write(6,*)' in interface routine igeofile =',igeofile
li = len(igeofile)
call gm_start_cad1(igeofile,li,lugeo_in,isemod,split2)
return
end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What syntrax is used in the compiler directive to specify the way of passing arguments? i.e. som by value, some by address.I have dug through the documentation - it says you can do it but I could find no example.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think I have it going now - if I add REFERENCE then the string length is embeded automatically. I would still like to know how to specify reference/value for individual arguments as I will need this.
many thanks for the help!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
!DEC$ ATTRIBUTES REFERENCE :: argname
or
!DEC$ ATTRIBUTES VALUE :: argname
as appropriate.
I highly recommend a careful read of the "Mixed-Language Programming" chapter of the Intel Fortran Building Applications manual.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am still a little confused, what does the complete compiler directive look like? I tried the following and it did not work
subroutine gm_start_cad(igeofile,lugeo_in,isemod,split2)
character*(*) igeofile
logical split2
interface
subroutine gm_start_cad1(igeofile,lugeo_in,isemod,split2)
CDEC$ ATTRIBUTES REFERENCE, DECORATE, STDCALL :: gm_start_cad1
CDEC$ ATTRIBUTES MIXED_STR_LEN_ARG, ALIAS:'GM_START_CAD':: gm_start_cad1
character*80 igeofile
integer lugeo_in, isemod
CDEC$ ATTRUBUTES REFERENCE :: isemod
logical split2
end subroutine gm_start_cad1
end interface
li = len(igeofile)
call gm_start_cad1(igeofile,lugeo_in,isemod,split2)
c
return
c
end
c
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have got the call to gm_start_cad working - thanks! I am now using the same technique in a different part of the code to callC routine compiled with cl from Vstudio 6.6 (STDCALL). The C routines I was looking at previously were compiled with VS 2003and /Gz
The interface block is included below. If I compile & linkthis under CVF 6.6c then it runs - as expected, the compiler directivesshould mimick the default calling convention. If I try this under Ifort i get an undefined external
aea_utilities.o : error LNK2019: unresolved external symbol _IOCNTF@136 referenc
ed in function _CHECK4
The library has an entry for _ICONTF@128 (nm -a).
A couple of questions:
a) Has something changed with the @nbytes between 6.6 and ifort?
b) Can I call VS 6.6 C routines from ifort compiled fortran?
interface
subroutine iocntf(ireq,ierror,errmsg,
. cwhat,cwhere,iwhen,
. nattrb, attrbs,
. nstrct, cdtype, block,iaddrs,naddrs,
. cstr, ndums,
. cdum, ndumc,
. idum, ndumi,
. rdum, ndumr,
. ddum, ndumd,
. cldm, nduml)
c#if defined (IWIN32) || DEFINED (IWIN64)
CDEC$ ATTRIBUTES REFERENCE,DECORATE,STDCALL ::iocntf
CDEC$ ATTRIBUTES MIXED_STR_LEN_ARG, ALIAS:'IOCNTF'::iocntf
c#endif
integer ireq, ierror
external errmsg
character*80 cwhat,cwhere
integer iwhen
integer nattrb
character*80 attrbs(20)
integer nstrct
character*80 cdtype
&n
bsp; integer block
__io_offset_type__ iaddrs(*)
integer naddrs
character*80 cstr(*)
integer ndums,ndumc,ndumi,ndumr,ndumd,nduml
character*1 cdum(*)
integer idum(*)
real rdum(*)
double precision ddum(*)
character*1 cldm(*)
end subroutine iocntf
end interface
C
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm somewhat puzzled by the declarations in your interface block - is cstr really an array of character*80 elements? Is cdum an array of single characters?
If you want the Fortran compiler to not pass the string lengths, you need to add:
CDEC$ ATTRIBUTES REFERENCE :: argname
for each of the CHARACTER arguments. This would have been the case in CVF as well. You don't need the MIXED_STR_LEN_ARG attribute then as there will be no lentgth arguments.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think I have figured ot what is going onhere. If I define an interface block as
subroutine gm_tol_cad(tol)
interface
subroutine gm_tol_cad1(tol)
CDEC$ ATTRIBUTES REFERENCE,DECORATE,STDCALL ::gm_tol_cad1
CDEC$ ATTRIBUTES MIXED_STR_LEN_ARG,ALIAS:'GM_TOL_CAD'::gm_tol_cad1
end subroutine gm_tol_cad1
end interface
call gm_tol_cad1(tol)
return
end
The the code links and runs as expected. If I declare tol to be real*8 in the subroutine and interface block them the linker fails looking for _GM_TOL_CAD@8 This seems to imply that the argument length has increased from 4 to 8 bytes whentol is promoted to double precision. With the CVF 6.6 compiler the byte length was always 4 (the address length) irrespective of the precision of tol. Is this the intended behaviour? Is there any way of keeping the 4 byte length
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
TheFORTRAN calling routinelooks like.
real*8 tol
call gm_tol_cad(tol)
end
subroutine gm_tol_cad(tol)
real*8 tol
interface
subroutine gm_tol_cad1(tol)
CDEC$ ATTRIBUTES REFERENCE,DECORATE,STDCALL ::gm_tol_cad1
CDEC$ ATTRIBUTES MIXED_STR_LEN_ARG,ALIAS:'GM_TOL_CAD'::gm_tol_cad1
real*8 tol
end subroutine gm_tol_cad1
end interface
call gm_tol_cad1(tol)
return
end
What seems to work is adding an explicit declaration to pass tol by reference .i.e
CDEC$ ATTRIBUTES REFERENCE :: tol
the code now links with tol specified as *4 or *8.
I thought the "REFERENCE" attribute in the first directive would pass everything by REFERENCE. This seems to imply tol gets passed by value unless explicity specified as reference. Am I missing something here?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page