- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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
Link Copied
1 Reply
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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

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