Silverfrost Forums

Welcome to our forums

Problem linking DLLs

25 Aug 2008 4:03 #3736

Consider the following trivially simple program:

PROGRAM t
 USE numbers
 IMPLICIT NONE
 CALL init_numbers ()
 WRITE(*,*) dp,e
END PROGRAM t

This program uses the following module:

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.

25 Aug 2008 5:56 #3738

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.

25 Aug 2008 7:53 #3739

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

26 Aug 2008 8:52 #3743

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.

26 Aug 2008 2:04 #3746

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.

26 Aug 2008 3:43 #3751

If the problem persists then zip up the whole project and send it to Silverfrost for forwarding to me.

26 Aug 2008 3:48 #3752

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.

2 Sep 2008 4:22 #3772

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.

3 Sep 2008 10:55 #3780

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?

3 Sep 2008 7:45 #3782

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:

  1. Use a static library rather than a DLL, or
  2. 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.
4 Sep 2008 4:26 #3784

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 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 echodll.obj file

4 Sep 2008 8:06 #3787

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.

5 Sep 2008 12:02 #3797

Use winzip to shrink the executable.

6 Sep 2008 7:27 #3802

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.

6 Sep 2008 2:42 #3803

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

Please login to reply.