View previous topic :: View next topic |
Author |
Message |
RichardMay
Joined: 02 May 2006 Posts: 25
|
Posted: Mon May 08, 2006 4:55 am Post subject: Calling functions in dlls |
|
|
I have a function in a dll that starts as shown below. How do I call it from an external program? When I use /import_lib in the FTN95 command line I get a floating point stack fault when I run the program.
f_stdcall integer function aqvbrao2(model,struct,direction,frequency,freedom, &
ampphase,raoval)
character*(*) model,freedom,ampphase
integer struct
real direction,frequency,raoval
Richard May |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Mon May 08, 2006 10:04 am Post subject: Calling functions in dlls |
|
|
Richard
In normal usage /import_lib is used to create an FTN95 executable that imports a library created using a third party compiler such as CVF.
Similarly in normal usage f_stdcall is used when creating an FTN95 DLL for use with an executable created for a third party compiler such as Visual Basic.
If you are using FTN95 for both the DLL and the executable then it is advisable not to use /import_lib and not to use f_stdcall.
If you must use one or other of these features then you may well experience difficulties when passing more than one character variable argument. It is advisable to pass at most one character variable argument. A single character argument should be the last in the argument list. This is because different protocols use different mechanisms for passing hidden arguments that specify the lengths of the character variables. |
|
Back to top |
|
|
RichardMay
Joined: 02 May 2006 Posts: 25
|
Posted: Tue May 09, 2006 9:00 am Post subject: Calling functions in dlls |
|
|
We are creating a dll for use with 3rd party compilers such as VB, CVF, Intel etc. This is why F_STDCALL is needed. But I work with FTN95 and would like to be able to test the .dll using FTN95. Surely this is possible?
Richard May |
|
Back to top |
|
|
Anonymous Guest
|
Posted: Wed May 10, 2006 3:41 am Post subject: Calling functions in dlls |
|
|
I use a Delphi main program as a GUI, with a ftn95 DLL to do the work (still win32 - I don't use .NET).
I do not use any compiler options to set the calling convention, so I end up with a cdecl calling convention (this is a carry-over from the ftn77 compiler, where there was no choice).
In the Delphi, the DLL procedures are declared as cdecl & external. Delphi is case-insensitive, so no issues there. This works OK for me.
You can test (I assume you mean debug?) the dll using sdbg. Just compile with /debug & link.
Then debug the main program with sdbg. It should stop to let you set break points when a routine in the DLL is first called.
Of course, you'll have to use the debugger for your GUI to test whether you are calling the fortran correctly...
You can put your fortran stuff into a module, but you will have to tell slink:
export MYFUNC=MYMODULE!MYFUNC
where MYFUNC on the LHS is what is exported, and MYMODULE!MYFUNC is the symbol generated by the compiler and is what you would export with exportall i.e. myfunc is contained in module mymodule).
|
|
Back to top |
|
|
RichardMay
Joined: 02 May 2006 Posts: 25
|
Posted: Wed May 10, 2006 4:59 am Post subject: Calling functions in dlls |
|
|
John,
Thanks for taking the time to reply to my question. We can call the dll OK from programs compiled with VB, CVF and Intel - the problem I have is calling it from a FTN95 program. As this is (or will be) part of a commercial program, not just an in-house tool, it needs to slot into our existing QA structure.
As well as debugging I need to be able to run a set of standard tests using the dll exactly as supplied to our clients, and I would prefer to run these using a program compiled with FTN95. It seems strange to me that if I use F_STDCALL in declaring the functions and create the dll using FTN95, I can call them from a CVF program but not from a FTN95 program.
Richard May |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Wed May 10, 2006 5:43 am Post subject: Calling functions in dlls |
|
|
You could try using /F_STDCALL from the FTN95 command line (see the forum Knowledge Base).
With this switch you would not use /IMPORT_LIB and omit F_STDCALL from the subprogram definition. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Wed May 10, 2006 5:47 am Post subject: Calling functions in dlls |
|
|
By this I mean use /F_STDCALL when creating a DLL for external use and leave it off for internal testing. |
|
Back to top |
|
|
RichardMay
Joined: 02 May 2006 Posts: 25
|
Posted: Thu May 11, 2006 1:41 am Post subject: Calling functions in dlls |
|
|
Some comments.
1. When I tried this I found that the decorated exported names were different using the /f_stdcall compiler option from those where F_STDCALL is in each individual file. Is this correct, or did I do something wrong? Is the compiler option case-sensitive?
2. The notes on the web-site say:
"Because of these limitations, /F_STDCALL should only be used when necessary and as an alternative to applying F_STDCALL to every exported subprogram." I take this to imply that it is better not to use /F_STDCALL, and since this is a commercial program I want to use the most reliable option.
3. It requires having two versions of the dll, one for release and one for testing. If possible I want to perform my tests using the release version, otherwise we have to build in another layer of checking to ensure that the two versions are consistent. While it may be OK to have a different version for development and debugging, we ought to be able to run the release version in-house.
Richard May |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Thu May 11, 2006 2:01 am Post subject: Calling functions in dlls |
|
|
Richard
1. They should be the same. The option is not case-sensitive.
2. If /F_STDCALL does not work then it will be apparent via a linkage error either when linking or at runtime.
3. /IMPORT_LIB is not designed for use with FTN95 DLLs. A possible alternative is to declare your routines as F_STDCALL at every point where they are called. |
|
Back to top |
|
|
RichardMay
Joined: 02 May 2006 Posts: 25
|
Posted: Thu May 11, 2006 5:42 am Post subject: Calling functions in dlls |
|
|
Paul,
I sent the dll created with the /F_STDCALL compiler option to one of my colleagues who is using the CVF compiler to test the interface. This was his reply.
"It did not work and even the link failed. When I checked the export symbols, I noticed that the decorated names were different (e.g. _AQVBRAO2@40 becomes _AQVBRAO2@68 now). Thus, it seems that this compiler option is not appropriate."
I.e. using F_STDCALL in the routine gave a decorated name of _AQVBRAO2@40, but the /F_STDCALL option gave _AQVBRAO2@68. If this is not because of differences in the two methods, what else could be the reason for this?
If I want to declare the routines as F_STDCALL at every point where they are called, what is the syntax for this?
Richard May |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Thu May 11, 2006 6:34 am Post subject: Calling functions in dlls |
|
|
Richard
For a SUBROUTINE sub simply declare
F_STDCALL sub
For a REAL FUNCTION func declare
F_STDCALL func
REAL func
You have 3 CHARACTERs, 1 32 bit INTEGER and 3 32 bit REALs, so your count is 7 + 3 for the hidden lengths. 10*4 = 40 so @40 is the correct decoration unless you are using debugging options which could had extra hidden arguments (an extra 9 arguments to get @68 sounds extreme). The other possibility is that you have changed the REAL precision. Failing this, yes you have encountered a bug in /F_STDCALL. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Thu May 11, 2006 6:43 am Post subject: Calling functions in dlls |
|
|
Incidentally, if you a passing more than one CHARACTER variable from an FTN95 DLL to a CVF executable then I would not expect any success. In this context FTN95 handles the STDCALL but does not change the position of the hidden length arguments (if my memory serves me correctly).
FTN95 and CVF use different orderings for the hidden length arguments and (as I mentioned earlier) there is no way round this other than to limit yourself to one CHARACTER argument in the list and to make this the last argument. |
|
Back to top |
|
|
|