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

Linking Fortran with a C++ dll

celiro
Beginner
531 Views
I have a VC6 C++ dll which exports several methods which i would like to link from Intel Fortran, the C code is about :

__declspec(dllexport) int WINAPI FGETS(int &a)
{
int b = a;
// do something here
return(b);
}

the def file removes the decoration by using Alias :

EXPORTS
_FGETS = _FGETS@4

and I call the method from Fortran as

external FGETS
integer i, j
i = 5
j = FGETS(i)
j = FGETS(i)

the linker works correctly (producing the executable) and when I debug the program it appears that Fortran correctly calls GETS by passing (first call) the correct value of i (5) , unfortunately I saw that the memory address of i (as passed to the C method) was :

0x0012FF74 (first call)
0x0012FF78 (second call)
0x0012FF7c (third call)

the C method receives the correct value only on first call, on subsequent calls the values were uncorrect.
I did presume that the address of i shouldn't change and I am not able to figure out why, any suggestions ?

Roberto

0 Kudos
2 Replies
Jugoslav_Dujic
Valued Contributor II
531 Views
You have calling conventions mismatch (and that's probably the root cause). WINAPI means __stdcall, but the default for Intel Fortran is __cdecl. Since stdcall and cdecl routines clean stack differently, you have a "fandango on stack" case (cause of many tough-to-catch bugs).

Your linking succeeded because you cheated -- basically, you renamed the export to match the C calling convention, but the stack is still screwed. By renaming, you removed the symptoms of LNK2001, but not the cause.

So, either remove WINAPI attribute and .def file on C++ side, or specify a correct interface on Fortran side, i.e. instead of external FGETS write:
interface
   integer function FGETS(a)
   !dec$attributes stdcall, alias: "_FGETS": FGETS
   integer:: a
   end function
end interface
Jugoslav

P.S. cdecl-style renaming will still cause confusion with eventual maintainers/users of the code ;-).
0 Kudos
celiro
Beginner
531 Views
thanks for the suggestion, I am going to test the std. C call (_cdecl), unfortunately we have different Fortran compilers and it seems difficult to find out a solution working on different platforms,

Roberto
0 Kudos
Reply