- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
INTERFACE SET_VARIABLE
MODULE PROCEDURE SET_VARIABLE_REAL
MODULE PROCEDURE SET_VARIABLE_INTEGER
MODULE PROCEDURE SET_VARIABLE_REAL_ARRAY
MODULE PROCEDURE SET_VARIABLE_INTEGER_ARRAY
END INTERFACE SET_VARIABLE
this interface is defined in a Module and also the module procedure. We want to export the SET_VARIABLE as the dll-function for main_programm. But we don't know how. I want to know if it's possible to export it and HOW?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For example, with the four specific subroutines that are involved in your example, withe module named as SETVMOD, the following module definition file will work.
[bash]LIBRARY mproc.dll EXPORTS SETVMOD_mp_SET_VARIABLE_INTEGER SETVMOD_mp_SET_VARIABLE_INTEGER_ARRAY SETVMOD_mp_SET_VARIABLE_REAL SETVMOD_mp_SET_VARIABLE_REAL_ARRAY [/bash]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tried your methode. But it semms not working. I tried to use the general name "SET_VARIABLE", but i got a bug.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK. I try to explain my problem in detail.
As in the question mentioned we put a INTERFACE in a MODULE for different types of parameter. The MODULE PROCEDURE are defined in the MODULE as PRAVITE. I defined in the .def file the EXPORTS as below.
...
EXPORTS
SET_VARIABLE_REAL = M_ID_AGMA2101_mp_SET_VARIABLE_REAL
SET_VARIABLE_INTEGER = M_ID_AGMA2101_mp_SET_VARIABLE_INTEGER
SET_VARIABLE_REAL_ARRAY = M_ID_AGMA2101_mp_SET_VARIABLE_REAL_ARRAY
SET_VARIABLE_INTEGER_ARRAY = M_ID_AGMA2101_mp_SET_VARIABLE_INTEGER_ARRAY
...In a MODULE of the main programm I try to call the exported functions directly use CALL SET_VARIABLE without using a !DEC$ ATTRIBUTE DLLIMPORT :: [the function Name]. And I got the error at Compiling like this:
Fehler1 error LNK2019: Verweis auf nicht aufgelstes externes Symbol "_SET_VARIABLE" in Funktion "_M_IF_AGMA2101_mp_IF_AGMA2101".M_IF_AGMA2101.obj
And then I tried another way. I puted a INTERFACE in the MODULE of the main programm like this:
INTERFACE
SUBROUTINE SET_VARIABLE_INTEGER(NM_VARIABLE,VL_VARIABLE)
!DEC$ ATTRIBUTES DLLIMPORT :: SET_VARIABLE_INTEGER
END SUBROUTINE SET_VARIABLE_INTEGER
SUBROUTINE SET_VARIABLE_REAL(NM_VARIABLE,VL_VARIABLE)
!DEC$ ATTRIBUTES DLLIMPORT :: SET_VARIABLE_REAL
END SUBROUTINE
...
END INTERFACE
Fehler1 error #6285: There is no matching specific subroutine for this generic subroutine call. [SET_VARIABLE]
I think I made somewhere a mistake. Can you tell me the right way to do that?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is a simpler solution, which does not need renaming DLL symbols or directives.
First, the source for building the DLL and the .mod file, mproc.f90:
[fortran]module setvmod INTERFACE SET_VARIABLE module procedure SET_VARIABLE_REAL module procedure SET_VARIABLE module procedure SET_VARIABLE_REAL_ARRAY module procedure SET_VARIABLE_INTEGER_ARRAY END INTERFACE contains subroutine set_variable(x,v) integer,intent(out) :: x integer,intent(in) :: v x=v return end subroutine set_variable subroutine set_variable_real(x,v) real,intent(out) :: x real,intent(in) :: v x=v return end subroutine set_variable_real subroutine set_variable_integer_array(x,v) integer,intent(out) :: x(:) integer,intent(in) :: v(:) x=v return end subroutine set_variable_integer_array subroutine set_variable_real_array(x,v) real,intent(out) :: x(:) real,intent(in) :: v(:) x=v return end subroutine set_variable_real_array end module setvmod [/fortran]The .def file, mproc.def :
[bash]LIBRARY mproc.dll EXPORTS SETVMOD_mp_SET_VARIABLE SETVMOD_mp_SET_VARIABLE_INTEGER_ARRAY SETVMOD_mp_SET_VARIABLE_REAL SETVMOD_mp_SET_VARIABLE_REAL_ARRAY [/bash]Building the DLL and the import library for it:
[bash]s:> lib /def:mproc.def /machine:i386 s:> ifort /LD mproc.f90 mproc.exp [/bash]The main program which uses the module and will call the DLL for the module procedures, tmproc.f90:
[fortran]program tmproc use setvmod integer :: i,ia(5),j,ja(5) real :: x,xa(5),y,ya(5) do i=1,5 ia(i)=i*2-3 xa(i)=i*2.5-4.5 end do j=3; call set_variable(i,j); write(*,*)i call set_variable(ja,ia); write(*,*)ja y=3.5; call set_variable(x,y); write(*,*)x call set_variable(ya,xa); write(*,*)ya end program tmproc [/fortran]Build and run the program:
[bash]s:LANG>ifort tmproc.f90 mproc.lib s:LANG>tmproc 3 -1 1 3 5 7 3.500000 -2.000000 0.5000000 3.000000 5.500000 8.000000 [/bash]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In a MODULE of the main programm I try to call the exported functions directly use CALL SET_VARIABLE without using a !DEC$ ATTRIBUTE DLLIMPORT :: [the function Name]. And I got the error at Compiling like this:
Fehler1 error LNK2019: Verweis auf nicht aufgelstes externes Symbol "_SET_VARIABLE" in Funktion "_M_IF_AGMA2101_mp_IF_AGMA2101".M_IF_AGMA2101.obj
This mising symbol isn't decorated with the _MODULENAME_mp_ prefix, which indicates that the compiler thinks that procedure represented by the symbol is just a normal external procedure (not a module procedure). As per mecej4's example, the SET_VARIABLE interface needs to be PUBLIC in the module that defines it (everything in the module in his example is PUBLIC by default) and you need the appropriate USE M_ID_AGMA2101 statement in the scope where CALL SET_VARIABLE appears.
Note that it is illegal code to separately specify an interface for a module procedure (like you've done in the second stretch of code in post four with the subroutine statements inside the interface block). The interfaces for a module procedure must only be accessed by a USE statement.
Rather than tying my code to a particular compiler's name mangling scheme, I prefer to use the BIND suffix on the definitions of the individial procedures to give the procedure a linker name of my choosing. If the procedure has an external linker name, making it private seems a bit counter-intuitive to me, but I guess it has to work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Anyway, the accessibility of the generic routine is separate from the accessibility of the specific routines, so one could add
[fortran] private public :: set_variable [/fortran]after Line-1 in #5. The linker, however, usually does not inherit (courtesy of the compiler) PUBLIC/PRIVATE attributes, so the module definition file needs to contain entries for even the private procedure names.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Marking procedures that must be exported in a DLL private bothers me a little because you've got supposedly internal implementation detail (private procedure names and entry points) "visible" to the outside world. Normally such externally visible interfaces (in the non-fortran sense) to bits of code need to be well controlled - changes to the name or argument list require everything that dynamically links to the interface to be recompiled. When something is private to a module I take it as a cue that I can interfere with it within the confines of the module as much as I please, but that's not the case here.
(Some compilers do not emit a external link name for private entities when they are sure that the procedure can not be referenced from outside the module (not the case here with ifort's implementation - if the generic interface is public then the private procedure must have an external link name). Some compilers (including ifort at one stage, might be fixed now) omit the external name in corner cases where it is still required, causing link errors.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
have to DLLEXPORT all the specific procedures that may be referenced in a DLL.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page