- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
Then in the second Fortran DLL routine "sub2" we have been including this syntax:
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:
Updated syntax in sub2:
Thank you very much for your help and advice.
Regards,
Greg
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
Link Copied
10 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
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]It requires System.Runtime.InteropServices reference.(here goes your routine interface)[/cpp]
There are C, STDCALL, FastCall, ThisCall, Winapi conventions supported.
A.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.

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