- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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 kopiert
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
Also, please use "INTEGER, VALUE ::" instead of [VALUE], which is an undocumented Microsoft extension.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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.- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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.

- RSS-Feed abonnieren
- Thema als neu kennzeichnen
- Thema als gelesen kennzeichnen
- Diesen Thema für aktuellen Benutzer floaten
- Lesezeichen
- Abonnieren
- Drucker-Anzeigeseite