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

when ATTRIBUTES STDCALL should be used

Greg_T_
Valued Contributor I
1,239 Views
Hello,

We have a mixed language engineering program with a Visual Basic GUI that calls Fortran DLLs. Recently a second Fortran DLLcalled from the first Fortran DLL caused corruption of local variable values in the first DLL routine and a subsequent crash. For about 12 years we have been using the following syntax to set the DLL attributes for the variables passed between the two Fortran DLLs.

In the first Fortran DLL routine "sub1" we include this syntax:
[cpp]!DEC$ATTRIBUTES DLLIMPORT :: sub2
!DEC$ATTRIBUTES ALIAS : 'sub2' :: sub2
call sub2(v1,v2,v3)
[/cpp]

Then in the second Fortran DLL routine "sub2" we have been including this syntax:
[cpp]subroutine sub2(v1,v2,v3)
!DEC$ATTRIBUTES DLLEXPORT :: sub2
!DEC$ATTRIBUTES ALIAS : 'sub2' :: sub2
!DEC$ATTRIBUTES STDCALL :: sub2
!DEC$ATTRIBUTES REFERENCE :: v1,v2,v3
[/cpp]

The recent program crash "unknown exception" (not my favorite error)is due to local variable values in sub1 getting corrupted after the call to sub2. I think this syntax is necessary between VB and Fortran to correctly pass the variables "v1,v2,v3", but perhapsit is not needed between Fortran DLLs. After debugging trial-and-errorand reading articleson this Forum, it sounds like only the DLLIMPORT and DLLEXPORT attributes are needed between Fortran DLLs, sincethe detailsare taken care of in the *.lib file createdwhen buildingthe DLL.I reduced the attributes syntax and the program is working again. Testing showed that including the STDCALL attribute seems to be the cause of the local variable corruption and the subsequent crash. The local variables are not passed between the DLLs. Then omitting the STDCALL allows the program to run correctly. Here is the updated reduced syntax:

Updated syntax in sub1:
[cpp]!DEC$ATTRIBUTES DLLIMPORT :: sub2
[/cpp]

Updated syntax in sub2:
[cpp]!DEC$ATTRIBUTES DLLEXPORT :: sub2[/cpp]
We have been using the full attribute syntax for about 12 years for calls between Fortran DLLs. We felt that the full declarations of the variables "v1,v2,v3"would be more thorough, and had worked well. Has something recently changed in the way Fortran treats the STDCALL? Perhaps we have had variables getting corrupted for all these years using the full syntax and were just lucky to not have had any crashes. Why is the full attribute syntax causing this problem? Perhaps there is a compile flag that is old or needs to be set? Should we use the minimum syntax for calls between Fortran routines and the full syntax for calls between VB and Fortran? I would like to keep our many DLLs happy and content. :-)

Thank you very much for your help and advice.
Regards,
Greg
0 Kudos
10 Replies
ArturGuzik
Valued Contributor I
1,239 Views
Greg,

I might be wrong ... but 12 years means that you started that in the times CVF was the king, and STDCALL was a default calling convention. In IVF this (default) changed (calling mechanism is C, arguments passed by reference ....), so you had a mismatch, I guess. Once you removed explicit declaration, the dll(s) were adjusted again.

You have following options: /iface:{cref|stdref|stdcall|cvf|default}) and can use /iface:cvf flag to keep the compatibility with Compaq VF.


A.
0 Kudos
Greg_T_
Valued Contributor I
1,239 Views

Thank you for the information. That makes sense that the default calling convention would change over time. Knowing that it has changed will help us keep our DLLs working and up to date. Is there documentation available on this topic that I could reference? Perhaps in the Fortran help, on the Intel web site, or a book?

Thanks again for the help, and for advice on good documentation sources.

Regards,
Greg
0 Kudos
ArturGuzik
Valued Contributor I
1,239 Views
Greg,

I think that Intel Visual Fortran Compiler User and Reference Guides (html docs) are pretty clear on the issue. I always refer to Chapter Programming with Mixed Languages (in Buliding Application) and especially Section ATTRIBUTES Properties and Calling Conventions. Then you can take a look at details of iface switch and STDCALL, C, REFERENCE ... attributes. If there is still something unclear or tricky... then Steve or Jugoslav on this Forum will know the answer, as they know everything.

A.
0 Kudos
Steven_L_Intel1
Employee
1,239 Views
When you are calling a DLL from VB, the called routine ALWAYS must have the STDCALL calling convention (on IA-32). CVF defaulted to STDCALL but as noted by others, IVF uses the more common C convention. I would usually recommend use of a !DEC$ ATTRIBUTES STDCALL directive in the DLL routine to be called rather than using switches and project options.
0 Kudos
ArturGuzik
Valued Contributor I
1,239 Views
When you are calling a DLL from VB, the called routine ALWAYS must have the STDCALL calling convention (on IA-32).

I might be wrong but I believe as far as VB.NET goes (is VB6 still alive?) one can call dll(s) with other than STDCALL calling conventions. The settings can be defined using the following
[cpp] (here goes your routine interface)[/cpp]
It requires System.Runtime.InteropServices reference.

There are C, STDCALL, FastCall, ThisCall, Winapi conventions supported.

A.
0 Kudos
DavidWhite
Valued Contributor II
1,239 Views
Greg,

If the attributes you need to set for VB or another languagee conflict with the sharing between different Fortran DLL's, I have simply exported two separate entry points, each with the relevant attributes.So I export Sub_VB and and Sub_F with the relevnatattributes. Both of these then call the actual calculation routine within the DLL (entry not exported).

Hope this helps,

David

0 Kudos
Greg_T_
Valued Contributor I
1,239 Views
Hello,

Thanks to all ofyou for the very helpful information and confirmation of the correct ATTRIBUTES syntax in a DLL. I had hoped that a single attributes syntax would be possible so that the DLL could be called from either VB or Fortran, but defining two entry point routines with the appropriate syntax for each calling routine won't be much extra effort. I think there are only a very few routines that are used by both VB and Fortran. The suggested reference will also be very helpful.

Regards,
Greg

0 Kudos
Steven_L_Intel1
Employee
1,239 Views
Eh? There's no problem having just one version of the routine for both languages. The key is that the Fortran caller needs to be able to see that the routine is STDCALL. One way to do this is to write an explicit interface including the directives. A simpler way is to just add the directive to the calling routine (will usually work.)
0 Kudos
DavidWhite
Valued Contributor II
1,239 Views
Eh? There's no problem having just one version of the routine for both languages. The key is that the Fortran caller needs to be able to see that the routine is STDCALL. One way to do this is to write an explicit interface including the directives. A simpler way is to just add the directive to the calling routine (will usually work.)

Steve,
Can't find where I originally came across this problem, was a couple of years ago. I used STDCALL and all the arguments with REFERENCE - worked fine with VB. I got into serious difficulty from Fortran - I think it was to do with corrupted character arguments - maybe I wasn't able to change the caller to STDCALL to ended up with separate entry points.
David
0 Kudos
Steven_L_Intel1
Employee
1,239 Views
If you called the STDCALL entry point from a routine that thought it used the C interface, you'd corrupt the stack. That can be easy to do in some cases since the compiler generates two symbols for STDCALL routines, one with the @n decoration and one without for cases where you pass the routine as an argument. But it should work properly if everything is consistent.
0 Kudos
Reply