Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29285 Discussions

link error with ATTRIBUTES C or STDCALL

lbrannma
Beginner
509 Views
Hi All,

I create a Fortran DLL, following the example at www.compaq.com/fortran/examples/vc-example.html.

The Compaq on line documentation says that I can declare __stdcall in my calling C code or in my Fortran subroutine. However....

My Fortran code is simple:

SUBROUTINE MYFUNC(X,Y)
IMPLICIT NONE
!DEC$ ATTRIBUTES DLLEXPORT::MYFUNC1
REAL(8) X,Y
Y = 25.0*X
RETURN
END

The created DLL runs fine from my C main program.

However, if my ATTRIBUTES line above is replaced with:
!DEC$ ATTRIBUTES STDCALL, DLLEXPORT::MYFUNC1

I get a link error in my cmain.obj file,
unresolved external symbol _imp_MYFUNC1. I tried adding an ALIAS, and also C rather than STDCALL, to no avail.

I have this in my main.c file:

extern __declspec(dllimport) void __stdcall MYFUNC1
(double *x, double *y);

Any assistance will be appreciated.

Thanks,
Lance

0 Kudos
1 Reply
Jugoslav_Dujic
Valued Contributor II
509 Views
There seems to be a terminology confusion here. I'll try to clarify it.

Stdcall calling convention -- let's call it __stdcall in the sequel, since that's what it means in C++ -- implies that arguments are pushed to stack right-to-left, the called routine must clean the stack and routine name is decorated as _Routine@n.

The default calling convention in CVF is __stdcall. Thus, a CVF routine should be declared __stdcall in C++. However, the following modification rules also apply as CVF's defaults:
1) Exported symbols are uppercase;
2) All arguments are passed by reference, e.g. (double* x);
2) When there's a string argument, an additional argument containing string length is passed by value immediately after string address.

However, when you add !DEC$ATTRIBUTES STDCALL, it still means this is __stdcall calling convention, but the rules above are modified as follows:
1) Exported symbols are lowercase (unless an ALIAS is specified by the programmer);
2) All scalar arguments are passed by value (e.g. double x). Arrays are still passed by reference;
3) This rule still holds. You can specify !DEC$ATTRIBUTES REFERENCE for string argument to avoid passing that length argument.

Thus, when you put !DEC$ATTRIBUTES STDCALL, you have to modify the C code as well:

extern __declspec(dllimport) void __stdcall myfunc1
(double x, double *y);

Note, however, that y is an output argument, thus it has to be passed by reference. (It may be passed by value, but then its value cannot be returned to the caller). Thus, you must specify:

!DEC$ATTRIBUTES REFERENCE:: y

in the Fortran code to express that (because !DEC$ATTRIBUTES STDCALL implies call by value for scalars).

HTH
Jugoslav


0 Kudos
Reply