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 DLLIMPORT and DLLEXPORT compiler directives. 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:
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 cDEC$ ATTRIBUTES DLLIMPORT and DLLEXPORT compiler directives. These directives 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:
!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 the BLOCK DATA statement:
BLOCK DATA T
!DEC$ ATTRIBUTES DLLEXPORT :: /X/
COMMON /X/ C, B, A
REAL C, B, A
END
The 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
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
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 cDEC$ 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: