- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
HDF5/calling conventions/!dec$ attributes
I have a couple of questions on handling calling conventions. The first is that I have to make calls to different versions of the same library, one of which expects an underscore and the other does not. My program links to too many different things to change the global settings. For some calls, I can use an interface block.
interface
subroutine foo (i1, i2)
!dec$ attributes DECORATE, alias:'foo_'::foo
integer i1, i2
end subroutine foo
end interface
However, I haven't gotten this to work for variable length string arguments:
interface
subroutine foo (name)
!dec$ attributes DECORATE, alias:'foo_'::foo
character name*(*)
end subroutine foo
end interface
I get an error like:
Rdtwdw.obj : error LNK2019: unresolved external symbol _gettime_@36 referenced in function _rdtwdw
Is there a way to use the alias function without having to specify the argument declarations? Currently, when I switch libraries, I change the name of the subroutine call:
call foo_ (name)
!call foo (name)
And I comment out the incorrect one, but this is getting tedious.
The second (and the one I am more concerned about), I am trying to make calls to Fortran dlls (this is the HDF5 data base program) that have been built using the CVF calling conventions. But the rest of my program uses the Intel default settings. The HDF5 dll routines are in a module. When I try the following:
use HDF5 !required module for HDF5 calls
interface
subroutine H5OPEN_F (hdferr)
!dec$ attributes STDCALL ::H5OPEN_F
integer hdferr
end subroutine H5OPEN_F
end interface
call H5OPEN_F (hdferr)
I get:
Error: The procedure name of the INTERFACE block conflicts with a name in the encompassing scoping unit. [H5OPEN_F]
And things get worse, since the argument list for HDF5 calls can be very complicated. In the following subroutine, the variable "buf" could, for instance, be either an integer or a real array and it can be of variable number of dimensions of variable sizes and the last three arguments in the call list are all optional.
SUBROUTINE h5dwrite_f(dset_id, mem_type_id, buf, dims, hdferr, &
mem_space_id, file_space_id, xfer_prp)
IMPLICIT NONE
INTEGER dset_id ! Dataset identifier
INTEGERmem_type_id! Memory datatype identifier
TYPE, INTENT(IN) :: buf! Data buffer; may be a scalar
&nbs
p; ! or an array
DIMENSION(*), INTEGER(HSIZE_T), INTENT(IN) :: dims
! Array to hold corresponding
! dimension sizes of data
! buffer buf; dim(k) has value
! of the k-th dimension of
! buffer buf;
END SUBROUTINE h5dwrite_f
How would one ever write an interface statement for such a subroutine?
HDF5 is an open source program. However, it is a fairly involved, mixed language program. I have tried building it from the source code, but at run time, I get weird, memory leak, sort of behaviour that has me stumped.
Any suggestions for a simple way to use the provided dlls? Or is dealing with the HDF5 source code likely to be the path of least resistance? (Anyone else out there using HDF5 with non-CVF settings?).
Thanks for any suggestions (and for taking the time to read my long, winded post).
jarvus
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
First, add the attribute keyword DEFAULT; this will apply the default Intel calling convention even if you specified CVF in the command options. This will get rid of the decoration that you don't want. it is also a way to be able to call routines using the default calling conventions and those that are using CVF conventions.
Another attribute which you will find handy is NO_ARG_CHECK. this allows you to pass arguments of any type content or rank to the specific argument.
The error you got regarding the name conflict suggests that you had another declaration of the same name visible where you had the INTERFACE block.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve, thanks for the reply.
I had tried the NO_ARG_CHECK, without success. For instance, the following snippet of actual code produces the following error:
SUBROUTINE RDTWDW (TICRD)
CHARACTER*(*) TICRD
INTERFACE
SUBROUTINE GETIME (CH, I1, I2, I3, I4, I5, I6, I7)
!dec$ attributes NO_ARG_CHECK, alias:'getime_'::GETIME
END SUBROUTINE GETIME
END INTERFACE
CALL GETIME (TICRD, 1, 78, JUL1, M1, JUL2, M2, ISTAT)
Rdtwdw.obj : error LNK2019: unresolved external symbol getime_ referenced in function _rdtwdw
Debug/Unsteady.exe : fatal error LNK1120: 1 unresolved externals
I also tried skipping the argument list, but I get a different error.
SUBROUTINE GETIME
!dec$ attributes NO_ARG_CHECK, alias:'getime_'::GETIME
END SUBROUTINE GETIME
END INTERFACE
Error: The number of actual arguments cannot be greater than the number of dummy arguments. [GETIME]
If I remove the interface block and call GETIME_ (TICRD,...) it links and runs. Am I missing something simple here?
Regarding the CVF calling convention. I actually had my above example backwards. My overall compilor settings are STDCALL REFERENCE. So I really need to add a CVF convention. However, the following gives a syntax error on the !dec$ line.
interface
subroutine h5open_f (i1)
!dec$ attributes CVF ::h5open_f
integer i1
end subroutine h5open_f
end interface
Is there a way to specify CVF convention in an interface block? From what I have found searching Help, it doesn't look like it. If I specify CVF as a global settings, I will be writing interface blocks for weeks (months maybe) in order to make all my currently existing library calls.
When I try,
USE HDF5
interface
subroutine h5open_f (i1)
!dec$ attributes STDCALL ::h5open_f
integer i1
end subroutine h5open_f
end interface
And get this error,
Error: The procedure name of the INTERFACE block conflicts with a name in the encompassing scoping unit. [H5OPEN_F]
I figured it was because h5open_f was inside a HDF5 module. If I don't have the "use HDF5" statement, it won't find the subroutine. If a subroutine is inside an already compiled module, is there no way to write an inteface block (and thus, no way to overwrite the calling convention to it)?
Would there be a way to solve this issue by writing a dll wrapper that goes between my main program and the HDF dlls?
I appreciate any suggestions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The comment about adding default got me thinking. So I startedplaying around with different variations of:
INTERFACE
SUBROUTINE GETIME (CH, I1, I2, I3, I4, I5, I6, I7)
!dec$ attributes NO_ARG_CHECK, DEFAULT, DECORATE, STDCALL, REFERENCE, alias:'getime_'::GETIME
END SUBROUTINE GETIME
END INTERFACE
The only one I could get to link was:
!dec$ attributes NO_ARG_CHECK, DEFAULT, DECORATE, alias:'getime_'::GETIME
However, it failed inside of the the getime call. getime is one of the calls inside of the main library I use. In order to use this library (I now remember) I had to change my global settings to STDCALL REFERENCE. Yet, when I try to add STDCALL, REFERENCE to the attributes line it won't link. But when it links with default it fails at run time because of the wrong calling convention.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you want the equivalent of a CVF interface, you need to specify the following attributes:
STDCALL,REFERENCE,NOMIXED_STR_LEN_ARG,DECORATE,ALIAS:"ROUTINE" :: ROUTINE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
GETIME is inside of a blackbox library. When I switched from Compaq/HP to Intel, and got the Intel black boxlibrary version,in order to make this call (and others) work: under Fortran/External Procedures I had to set STDCALL, REFERENCE, and I either had to set Append Underscore to YES or add it manually (GETIME_). (The remaining settings underExternal Procedureshave not been changed.) The first argument is a variable lengthstring (a calander date in one of several formats) and the remaining arguments are integers. That is all the info I have on settings. There are other calander libraries out there, but I have manyhundreds of calls to other routines in this library.
It all works without the interface block and I can make it work with the interface blocks for calls that don't involve strings. The calls with strings always fail with subroutine not found error.
But I will stick with manually changing the underscore for subroutines with strings for now.
Thanks for the info onhow to write theCVF interface equivalent (but wouldn't it have been nice if you could have just specified CVF?).
If I don't make progress on that front, I will try writing a dll wrapperthat alreadyhas the correct defaultsettings for calling HDF5. I will then try and handle the calling convention mismatch when I write the !DEC$ DLLEXPORT statement and see if I get any further.
Thanks once again for your time.

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