Coding Requirements for Sharing Data in
DLLs
A dynamic-link library (DLL) is an executable file
that can be used as a place to share data across processes.
Coding requirements include using the
cDEC$ ATTRIBUTES
compiler
directive DLLIMPORT and DLLEXPORT options. Variables and routines declared in
the program and in the DLL are not visible to each another unless you use
DLLIMPORT and DLLEXPORT.
When sharing data among multiple threads or
processes, do the following:
- Declare the order, size, and data types of shared data consistently in the DLL and in all procedures importing the DLL exported data.
- If more than one thread or process can write to the common block simultaneously, use the appropriate features of the Windows* operating system to control access to the shared data. Such features include critical sections (for single process, multiple thread synchronization) and mutex objects (for multi-process synchronization).
This section discusses:
Exporting and Importing Common Block
Data
Data and code in a dynamic-link library is loaded
into the same address space as the data and code of the program that calls it.
However, variables and routines declared in the program and in the DLL are not
visible to one another unless you use the
c
DEC$ ATTRIBUTES
compiler directive DLLIMPORT and
DLLEXPORT options. These directive options enable the compiler and linker to
map to the correct portions of the address space so that the data and routines
can be shared, allowing use of common block data across multiple images.
You can use DLLEXPORT to declare that a common
block in a DLL is being exported to a program or another DLL. Similarly, you
can use DLLIMPORT within a calling routine to tell the compiler that a common
block is being imported from the DLL that defines it.
To export and import
common block data:
- Create a common block in the subprogram that will be built into a Fortran DLL. Export that common block with!DEC$ ATTRIBUTES DLLEXPORT, followed by theCOMMONstatement, associated data declarations, and any procedure declarations to be exported. For example:!DEC$ ATTRIBUTES DLLEXPORT :: /X/ COMMON /X/ C, B, A REAL C, B, A END ...If the Fortran DLL procedure contains only a common block declaration, you can use theBLOCK DATAstatement:BLOCK DATA T !DEC$ ATTRIBUTES DLLEXPORT :: /X/ COMMON /X/ C, B, A REAL C, B, A ENDThe Fortran procedure to be linked into a DLL can contain a procedure, such as the following:SUBROUTINE SETA(I) !DEC$ ATTRIBUTES DLLEXPORT :: SETA, /X/ COMMON /X/ C, B, A REAL C, B, A INTEGER I A = A + 1. I = I + 1 WRITE (6,*) 'In SETA subroutine, values of A and I:' , A, I RETURN END SUBROUTINE
- Refer to the common block in the main program with!DEC$ ATTRIBUTES DLLIMPORT, followed by the local data declarations and any procedure declarations defined in the exported DLL. For example:PROGRAM COMMONX !DEC$ ATTRIBUTES DLLIMPORT:: SETA, /X/ COMMON /X/ C, B, A REAL C, B, A, Q EQUIVALENCE (A,Q) A = 0. I = 0 WRITE (6,*) 'In Main program before calling SETA...' WRITE (6,*) 'values of A and I:' , A, I CALL SETA(I) WRITE (6,*) 'In Main program after calling SETA...' WRITE (6,*) 'values of A and I:' , Q, I A = A + 1. I = I + 1 WRITE (6,*) 'In Main program after incrementing values' END PROGRAM COMMONX
- Build the DLL and then build the main program, as described in Building Dynamic-Link Libraries.
Exporting and Importing Data Objects in
Modules
You can give data objects in a module the DLLEXPORT
property, in which case the object is exported from a DLL.
When a module is used in other program units,
through the
USE
statement, any objects
in the module with the DLLEXPORT property are treated in the program using the
module as if they were declared with the DLLIMPORT property. So, a main program
that uses a module contained in a DLL has the correct import attributes for all
objects exported from the DLL.
You can also give some objects in a module the
DLLIMPORT property. Only procedure declarations in
INTERFACE
blocks and
objects declared
EXTERNAL
or with
c
DEC$ ATTRIBUTES
EXTERN can have the
DLLIMPORT property. In this case, the objects are imported by any program unit
using the module.
If you use a module that is part of a DLL and you
use an object from that module that does not have the DLLEXPORT or DLLIMPORT
property, the results are undefined.
For more
information:
- On building a DLL, see Building Dynamic-Link Libraries.