- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have been using BIND(C,NAME='SubName') within an interface block to call functions declared in a C++ library. The Fortran project calling convention is set to CVF (Properties > Fortran > External Procedures) and the equivalent C++ project setting is cdecl.
Does the use of BIND(C,...) force the use of cdecl? Or is it still necessary to explicitly specify the calling convention with the use of !DEC$ ATTRIBUTES C in the interface where the project settings do not match as above? I understand this is the case for stdcall, but was under the impression BIND(C,...) assumed cdecl. My program exhibits behaviour typical of stack corruption when I use BIND(C,...) with the settings mentioned above, but behaves correctly when I omit the BIND construct and include !DEC$ ATTRIBUTES C, DECORATE, ALIAS: 'SubName' ::SubName in the interface block.
Link Copied
- 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
Thanks. My program is crashing due to access violation whenever I call a C++ subroutine with arguments from Fortran (the crash behaviour is not reproducible if functions with no arguments are called). I have a few static variables declared in the C++ module although am not if this is likely to be the cause.
Fortran interface:
[fortran]INTERFACE
SUBROUTINE MySub (retVal, var1, var1, var3) BIND(C,NAME='MySub') INTEGER retVal INTEGER var1 [VALUE] INTEGER var2 [VALUE] INTEGER var3 [VALUE] END
!other subroutines...
END INTERFACE
(var2 is a dummy argument of type INTEGER) INTEGER :: retVal = 0 INTEGER :: var1 = 0
INTEGER :: var3 = 1 CALL MySub (retVal, var1, var2, var3) [/fortran]
C++ callee:
[cpp]//Static vars vectorclsV(20,NULL); //Declaration: extern "C" { void MySub (int *retVal, const int var1, const int var2, const int var3); } //Implementation: void MySub (int *retVal, const int var1, const int var2, const int var3) { ... }[/cpp]
The problem is likely to do with argument passing/stack cleanup, since the call succeeds when the arguments are removed.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Also, please use "INTEGER, VALUE ::" instead of [VALUE], which is an undocumented Microsoft extension.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please find attached a zip of a cut-down project that reproduces the access violation - please see the comments in test1.for. The call succeeds when the C++ function is exported as stdcall, or when no arguments are passed, implying stack corruption.
Note that this is only reproducible in release mode. I have set debug info /debug:minimal in Console1.vfproj - if set to /debug:full the issue is not reproducible.
I am using compiler version 11.1.046 and Visual C++ 9.0.30729.1 (Visual Studio 2008 SP).
Thanks for your help.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On 64-bit all function calls are fastcall (pass first few values via registers)
On 32-bit platform fastcall/ nofastcall is controlled by option switches, declspec, ATTRIBUTES etc.
Check to make sure fastcall is consistent
And, check to make sure int size is the same.
Alternate way to check:
Make a call to MySub from within the C++ side. Then compile both the Fortran and C++ modules making this call but add the option switch to produce the assembler output. Comparing the calling sequence might point you to the problem.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm using a 32-bit system, and all integer types line up (4-bytes signed). I've also tried setting the value types to pointers and removing const in the function name but this didn't work.
I'll take a look at the assembler output and see if it reveals anything.
Thanks
- 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 rebuilt using 11.1.060 and it runs fine on several machines. I have tested the "broken" version (11.1.046) on the same machines (both running in debugger and from command line) and get the same access violation issue. Is there any chance you could also test with 11.1.046 as a sanity check, in case some environment setting is causing the problem?
If this is a compiler issue, it possible to request a patch for compiler version 11.1.046? I don't think moving to a later compiler release is an option for us right now as we are gearing up for a release and would need to extensively re-test everything if using a newer compiler.
Many thanks.
- 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 still can't quite understand why this problem occurs in the attached project but not in other parts of my program where I am essentially doing the same thing: in the working cases I am passing in parameters of various types, including the first element of an assumed-shape array of reals, as well as single-byte and 4-byte ints. In fact, when I run the cut-down example with exactly the code that works in the project proper, it still fails. This had me thinking that I had not initialised something correctly, or that it was a calling convention issue, but doesn't explain why some examples succeed and others don't where all environment/project settings match.
In the release notes there is a reference to DPD200148942 Fortran Internal Compiler Error on Function returning pointer with BIND(C) which may be the fix.
- 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
As it's a compiler bug I think our only option is to move to version 060 when possible - sooner rather than later if it's only luck that we've not witnessed stack corruption until now!
Note that the problem is only evident when passing pointer variables to C, not value types.
Thanks for your help.

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