|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
Edwin
Joined: 25 Nov 2005 Posts: 3
|
Posted: Mon Dec 05, 2005 1:11 am Post subject: Calling a procedure inside a (Delphi) DLL using FTN77 (error |
|
|
I am using Salford FTN77/Win32. I want to call a subroutine which is in a (Delphi compiled) DLL file. This subroutine receives a lot of parameters, but I don't want to bother you with this (yet). So I simplified the program to just calling a subroutine without any parameters that produces a system beep.
Beep.dpr (this is the Delphi library that compiles the DLL file):
library MyBeep;
uses SysUtils; // Delphi unit SysUtils contains beep procedure
procedure PlayBeep; stdcall
begin Beep; end;
exports PlayBeep; // To export the beep procedure to the DLL.
end.
Beeptester.dpr (this is a delphi program creating an executable that can call the procedure from the DLL):
program BeepTester;
procedure PlayBeep; external 'Beep.dll';
begin PlayBeep; end.
Beeptester.for (this should be the fortran equivalent of Beeptester.dpr, but it does not work):
program BeepTester
stdcall PlayBeep
call PlayBeep
end
The executable from the fortran code gives an error message:
Error 29, Call to missing routine: _PlayBeep@0 at 0x00401017
This error makes sense to me cause the program can not find the subroutine PlayBeep since I did not specify that it is in 'Beep.dll'.
But how can I fix this problem? In other words, can anyone provide me the FTN77 equivalent of the Delphi code of Beeptester.dpr?
If anyone needs any code (FOR, DPR, DLL, EXE, etc) from me, just drop me a message. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7930 Location: Salford, UK
|
Posted: Mon Dec 05, 2005 2:26 pm Post subject: Calling a procedure inside a (Delphi) DLL using FTN77 (error |
|
|
Edwin
The immediate thought that comes to mind is "do you have to do it this way"?
1. Are you forced to use FTN77? FTN95 is the natural choice. The only reason for prefering FTN77 is if you are developing for commercial use and do not want the buy an FTN95 licence (FTN95 is free for personal use).
2. Accessing a DLL written in Pascal is not a natural choice (for either FTN77 or FTN95). Fortran or C are the natural choices for the DLL. If you are only calling Windows API functions then you can access the Windows API directly (the Windows API DLLs are written in C). If you must access a Pascal DLL then you will find the interface difficult to sort out and, to my knowledge, you may well be the first person to try to do this. You may get some help from the FTN77 or FTN95 documentation about calling C from Fortran but the calling convention for Pascal is different. |
|
Back to top |
|
|
Edwin
Joined: 25 Nov 2005 Posts: 3
|
Posted: Tue Dec 06, 2005 6:50 am Post subject: Calling a procedure inside a (Delphi) DLL using FTN77 (error |
|
|
Paul
1. Yes I am developing for commercial use. I am using a licenced FTN77. I am not forced to using FTN77. Buying a FTN95 licence would not be a problem if it helps. Are the two compilers 100% compatible? The program I am developing consists of over 200 fortran files with almost 100.000 code lines. It works fine using FTN77, it uses little ClearWin+ code as well as some direct Windows API calls. The program has a one way communication with a GUI written in Delphi (another 50.000 code lines).
2. The reason I need to do this is a simple one. I have a numerical model in Delphi consisting of another 10.000 code lines. This model generates, given some input data, a result that is needed by my Fortran program. In other words, if I do not want to translate 10.000 code lines from Delphi to Fortran*, I have to find some way to transfer the data back and worth. Since the transfer will be done at least once per second, it needs to be a fast transfer method (no disk access). I can only think of using a DLL transfer method for this.
3. My main problem (at least until now) is not in the calling convention. I know it is different for Pascal, but Delphi has options to create DLL's using a C compatible calling convention. So I think I can find my way around the convention problems. My current problem is I can not find any documentation at all of how to call a function/procedure from a DLL. I can't find much about this in the FTN77 documentation (Users Guide). How would I call a function from inside a DLL if it was created by C or by FTN77 or FTN95? Let's forget about the fact that the DLL code comes from Delphi and go back to my main question:
What is the FTN77 equivalent of the following Delphi program:
program BeepTester;
procedure PlayBeep; external 'Beep.dll';
begin
PlayBeep;
end.
* Not only translating the 10.000 code lines would be quite a job. The other problem is that the code has been optimised for Delphi over the years. I tried translating some of the code from Delphi to FTN77, but this slowed down calculations by 2 to 3 times. Since the function takes 100 ms to run and will be called many 10.000 times, calculation speed is an important issue and that is where the well-optimised Delphi compiler shows its power. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7930 Location: Salford, UK
|
Posted: Wed Dec 07, 2005 12:39 am Post subject: Calling a procedure inside a (Delphi) DLL using FTN77 (error |
|
|
Edwin
I do not have the FTN77 documentation to hand but I think there is a chapter in the manual that has a section on "Calling C from Fortran". The keywords are STDCALL and C_EXTERNAL for the two standard calling conventions. If you cannot find this, the same information is in the online FTN95 documentation which (for this purpose) I suggest you download for free.
The matter of switching to FTN95 is relatively minor. FTN77 and FTN95 are designed to be totally compatible. Use the free version as a trial and see how you get on.
|
|
Back to top |
|
|
Edwin
Joined: 25 Nov 2005 Posts: 3
|
Posted: Wed Aug 30, 2006 3:57 am Post subject: Calling a procedure inside a (Delphi) DLL using FTN77 (error |
|
|
Paul,
I finally switched from FTN77 to FTN95 and this allowed me to also fix the issue of calling a Delphi DLL from within FTN, so I thought it would be good to add the solution to the forum. The solution is very simple, at least when using FTN95. Not sure how to do this with FTN77, but I no longer need to do that.
First step is to add the DLL (in this case beep.dll) to the reference list of the FTN95 project.
Second point is that I simply forgot to add an extra 'PlayBeep' in the second codeline (see below).
Beeptester.for (this should be the fortran equivalent of Beeptester.dpr, it does work now):
program BeepTester
stdcall PlayBeep 'PlayBeep'
call PlayBeep
end
That's all. Now I can easily call any kind of function or procedure (also with more complex parameters), as long as I force my Delphi compiler to create 'stdcall' code in the DLL. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|