Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29238 Discussions

DLL subroutines requiring an interface and using derived type arguments

OP1
New Contributor III
477 Views

I want to create a DLL which contains the following subroutine:

SUBROUTINE MY_SUB(MY_VAR)
!DEC$ ATTRIBUTES DLLEXPORT :: MY_SUB
USE MY_DLL_MODULE! The type MY_TYPE is declared here.
IMPLICIT NONE
TYPE(MY_TYPE),ALLOCATABLE,INTENT(INOUT) :: MY_VAR(:)
... do some work here ...
END SUBROUTINE MY_SUB

The main program, which calls the DLL subroutine, will look like this:

PROGRAM MY_PROG
USE MY_PROGRAM_MODULE ! The type MY_TYPE isre-declared here.
IMPLICIT NONE

INTERFACE
SUBROUTINE MY_SUB(MY_VAR)
!DEC$ ATTRIBUTES DLLIMPORT :: MY_SUB
IMPLICIT NONE
TYPE(MY_TYPE),ALLOCATABLE,INTENT(INOUT) :: MY_VAR(:)
END SUBROUTINE MY_SUB
END INTERFACE

TYPE(MY_TYPE),ALLOCATABLE :: MY_VAR(:)

CALL MY_SUB(MY_VAR)
END PROGRAM MY_PROG

My question relates to where I need to declare the type MY_TYPE. It seems that I need to declare it both in MY_DLL_MODULE and in MY_PROGRAM_MODULE. That sounds redundant. Is there any way to have the type declared in the DLL, then this type is made accessible (exported) to the main program? My understanding is that only module objects can be exported; not types.

I hope I explained this clearly enough...

Olivier

0 Kudos
2 Replies
DavidWhite
Valued Contributor II
477 Views
Quoting - opmkl

I want to create a DLL which contains the following subroutine:

SUBROUTINE MY_SUB(MY_VAR)
!DEC$ ATTRIBUTES DLLEXPORT :: MY_SUB
USE MY_DLL_MODULE! The type MY_TYPE is declared here.
IMPLICIT NONE
TYPE(MY_TYPE),ALLOCATABLE,INTENT(INOUT) :: MY_VAR(:)
... do some work here ...
END SUBROUTINE MY_SUB

The main program, which calls the DLL subroutine, will look like this:

PROGRAM MY_PROG
USE MY_PROGRAM_MODULE ! The type MY_TYPE isre-declared here.
IMPLICIT NONE

INTERFACE
SUBROUTINE MY_SUB(MY_VAR)
!DEC$ ATTRIBUTES DLLIMPORT :: MY_SUB
IMPLICIT NONE
TYPE(MY_TYPE),ALLOCATABLE,INTENT(INOUT) :: MY_VAR(:)
END SUBROUTINE MY_SUB
END INTERFACE

TYPE(MY_TYPE),ALLOCATABLE :: MY_VAR(:)

CALL MY_SUB(MY_VAR)
END PROGRAM MY_PROG

My question relates to where I need to declare the type MY_TYPE. It seems that I need to declare it both in MY_DLL_MODULE and in MY_PROGRAM_MODULE. That sounds redundant. Is there any way to have the type declared in the DLL, then this type is made accessible (exported) to the main program? My understanding is that only module objects can be exported; not types.

I hope I explained this clearly enough...

Olivier


Olivier,

You could add a third module, MY_TYPES, which simply defines the types in use. This would be then USEd by both the program and the DLL. The extra declares that are unique to the program or the DLL would remain in the original modules. This avoids the redundancy, and possibilty of errors in the declares.

David
0 Kudos
Steven_L_Intel1
Employee
477 Views
My #1 rule - if you have written an INTERFACE block for Fortran code, you're doing it wrong.

Here's the general approach to take. Structure your DLL as a module like this:

[plain]module MY_MOD
type MY_TYPE
...
end type MY_TYPE
...
contains
subroutine MY_SUB (arg)
!DEC$ ATTRIBUTES DLLEXPORT :: MY_SUB
type(MY_TYPE), intent(INOUT) :: arg
...
end subroutine MY_SUB
end module MY_MOD[/plain]

Build this as a DLL project. Its output is the compiled module file (MY_MOD.mod) and the export library (MY_MOD.lib)

In the main program project, make the DLL project a "dependent" of the main project and add the appropriate output folder (Debug or Release) to the "Additional INCLUDE path" list in the main program's project

Now your main program can look like this:

[plain]program main
use MY_MOD
type(MY_TYPE) :: my_var
...
call MY_SUB(my_var)
...[/plain]
No need to redefine anything and the DLLEXPORT from the module turns into a DLLIMPORT on USE.
0 Kudos
Reply