View previous topic :: View next topic |
Author |
Message |
simon
Joined: 05 Jul 2006 Posts: 300
|
Posted: Mon Aug 25, 2008 5:03 pm Post subject: Problem linking DLLs |
|
|
Consider the following trivially simple program:
Code: |
PROGRAM t
USE numbers
IMPLICIT NONE
CALL init_numbers ()
WRITE(*,*) dp,e
END PROGRAM t
|
This program uses the following module:
Code: |
MODULE numbers
IMPLICIT NONE
INTEGER, PARAMETER, PUBLIC :: dp=KIND(1.0d0)
REAL(KIND=dp), PARAMETER, PUBLIC :: one=1.0_dp
REAL(KIND=dp), PUBLIC :: e
CONTAINS
SUBROUTINE init_numbers ()
e=one
RETURN
END SUBROUTINE init_numbers
END MODULE numbers
|
If I create the module as a DLL, the following message is issued at compilation even though the DLL is specified as a reference:
WARNING the following symbols are missing:
MODULE NUMBERS .\CheckMate\Win32\t.obj
At runtime, the output is correct for dp, but nonsense for e.
Please advise what I am doing wrong. |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8252 Location: Salford, UK
|
Posted: Mon Aug 25, 2008 6:56 pm Post subject: |
|
|
You will need a copy of the .mod file in your project folder or alternatively you can use /MOD_PATH on the FTN95 command line. |
|
Back to top |
|
 |
simon
Joined: 05 Jul 2006 Posts: 300
|
Posted: Mon Aug 25, 2008 8:53 pm Post subject: |
|
|
Thanks Paul, but I have the mod-path correctly already. If the mod path is not specified I get an error message, if it is I get a warning message and the wrong output.
Simon |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8252 Location: Salford, UK
|
Posted: Tue Aug 26, 2008 9:52 am Post subject: |
|
|
The "Reference" is used at link time.
You will also need it to be "visible" at runtime.
E.g. you could copy the DLL to the exe folder. |
|
Back to top |
|
 |
simon
Joined: 05 Jul 2006 Posts: 300
|
Posted: Tue Aug 26, 2008 3:04 pm Post subject: |
|
|
The DLL is in the exe folder already. I have tried compiling both from the command line and from within Plato, and get the same warning message. In the program, if I print only dp, and not e, then there warning message disappears, and the program works properly. |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8252 Location: Salford, UK
|
Posted: Tue Aug 26, 2008 4:43 pm Post subject: |
|
|
If the problem persists then zip up the whole project and send it to Silverfrost for forwarding to me. |
|
Back to top |
|
 |
IanLambley
Joined: 17 Dec 2006 Posts: 506 Location: Sunderland
|
Posted: Tue Aug 26, 2008 4:48 pm Post subject: |
|
|
Did I read somewhere that you can't or shouldn't pass things to DLLs via common block. Does the same apply to modules. Or am I crazy?
Ian
PS last question was rhetorical. |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8252 Location: Salford, UK
|
Posted: Tue Sep 02, 2008 5:22 pm Post subject: |
|
|
Certainly there is a similarity between module data and common block data.
I can confirm the behaviour that you describe and I assume that you are attempting the impossible (holding module data in a DLL).
I will see if I can get any further information on this. |
|
Back to top |
|
 |
simon
Joined: 05 Jul 2006 Posts: 300
|
Posted: Wed Sep 03, 2008 11:55 am Post subject: |
|
|
Many thanks for investigating this. Given that I am apparently trying to do something illegal, could I get some advice on how to restructure my program? The issues are as follows:
1. I have a set of parameters that I presumably need to define in the main program rather than the DLL.
2. These parameters need to be accessed by subroutines within the DLL.
3. The subroutines in the DLL need to be called by the main program.
Should I define a separate module with parameter definitions, which is available to the DLL when I compile it, but which is linked into the main program?
Or am i Just making things too messy and complicated, and am missing a more obvious way of structuring the program? |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8252 Location: Salford, UK
|
Posted: Wed Sep 03, 2008 8:45 pm Post subject: |
|
|
At this stage I am not sure that you cannot store Fortran data in this way. In the past it was possible to store common block data but that may have been under DBOS rather than Win32. I should be able to get more information tomorrow.
There are various alternatives. Here are two to start off:
a) Use a static library rather than a DLL, or
b) Create your data in the executable, put it into an array and pass
the array (it will be by reference, i.e just the base address) with each
library call. |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2620 Location: Sydney
|
Posted: Thu Sep 04, 2008 5:26 am Post subject: |
|
|
I can recall that you can't use modules in .dll's, but can't recall where it is stated.
I've been using static libraries for years, with common blocks to share data. All common blocks are defined using include files. I even place some in the Salford/Silversoft include directory.
I have not tried replacing commons with modules in these static libraries as most of my libraries predate modules. I think that it is possible to use modules.
Static libraries work very well, especially for data sharing, although I have not required the extra functionality provided by .dll's.
The following is the example of the very few commands required to make a .lib static library.
A sample batch file consists of:-
now >make.tce
del *.obj >>make.tce
ftn95 binin /optimise >>make.tce
{ftn95 commands omitted}
ftn95 echodll >>make.tce
*
del saplib.lib >>make.tce
slink saplib.txt >>make.tce
del *.obj >>make.tce
saplib.txt consists of:-
archive saplib.lib
addobj binin.obj
{addobj commands omitted}
addobj echodll.obj
file |
|
Back to top |
|
 |
simon
Joined: 05 Jul 2006 Posts: 300
|
Posted: Thu Sep 04, 2008 9:06 am Post subject: |
|
|
Thanks to all who have responded. I think I have some good suggestions to work from.
I had initially been interested in using the DLLs because the executable for the software I have developed is starting to get too large for many of my clients to download (it is used primarily in countries with very poor internet connections). A solution seemed to be to break the program into various components using DLLs, and then when an upgrade is released only the relevant DLL or .EXE file need be downloaded. I believe I won't have this advantage with static libraries.
Anyway, I'll wait to hear what Paul finds out, and at the worst will think about modifying how I have structured and what I include in the DLLs. |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2620 Location: Sydney
|
Posted: Fri Sep 05, 2008 1:02 am Post subject: |
|
|
Use winzip to shrink the executable. |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8252 Location: Salford, UK
|
Posted: Sat Sep 06, 2008 8:27 am Post subject: |
|
|
This is to confirm that we not expect that module data within a DLL will be directly accessible from the main program.
The data will probably be accessible from within DLL module procedures and accessible from the executable via a "GetValue" function.
At the same time, users should be aware that DLLs may not be guaranteed to remain loaded during the execution of a program so that it may be necessary to use the Windows API functions LoadLibrary and FreeLibrary in order to preserve DLL data. |
|
Back to top |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2413 Location: Yateley, Hants, UK
|
Posted: Sat Sep 06, 2008 3:42 pm Post subject: |
|
|
Simon,
Re: "...is starting to get too large for many of my clients to download..." and John's suggestion to use WinZip, here is another possiblity.
I use Inno Setup (free!) to create a single EXE that contains the compiled EXE and SalfLibC.dll and various other things. The resulting setup program is compressed ("zipped"). Just checking an example showed 2740kb were shrunk into 1620 kb.
Eddie |
|
Back to top |
|
 |
|