Is there any way to use a module of the calling program within a DLL?
Thanks for any help or information,
Detlef
Welcome to our forums
Is there any way to use a module of the calling program within a DLL?
Thanks for any help or information,
Detlef
No. Not in a direct way.
Modules contain data and subprograms that should operate on the data. The usual way to pass data (and I guess subprograms) from an executable to a DLL would be via an subprogram argument list.
For a fuller explanation, it would help if you could give more details about what you have in mind. Do you want to pass both data and subroutines?
I want to separate some parts of a large program in a DLL. The modules are containing only data. Because the amount of data used is very large, a subprogram argument list gets very long.
There is also another question:
Is it possible to call subroutines of the main program to call from within the DLL?
Modules are a good way to define a data structure and contain routines that operate on that data structure.
I am not a user of DLLs and don't understand why they are essential. I also use static libraries, which include modules and these work well with slink. I am not sure if DLL's can't also include modules. If they can then they would operate similar to libraries. I think the key point is that routines that operate on the module database should be contained with the module, while third party or other DLL's should have a more generic database interface.
Again, going down the module path, using derived type data structures, I would consider it essential to operate on these data structure via a CONTAINS or USE. The DLL needs to know the data structure, which means that it has a USE. The derived type data structure is a key component of teh program operation.
Can someone clarify if you can use modules in a DLL and if so they should be defined in the DLL. If not then DLL's should be used in a more general way.
John
The key to passing a large amount of data is to pack the data into a structure (i.e. a Fortran user-defined type). Then pass the structure (i.e. its address) as an argument. The DLL will know the form of the structure and can access data members that way.
The usual way to call local subprograms from a DLL is to pass the subprogram as an argument. This is what happens in ClearWin+ when you use a callback function.
Do you have some small examples for both cases?
Passing data....
subroutine foo(obj)
type my_object
sequence
real real_member
integer integer_member
end type
type(my_object)::obj
obj%integer_member = 42
end subroutine foo
program main
type my_object
sequence
real real_member
integer integer_member
end type
type(my_object)::obj1
call foo(obj1)
print*, obj1%integer_member
end program main
Passing subroutines...
This is not what you need but it might help to point you in the right direction. It's been a long day.
subroutine foo(val)
integer val
print*,val
end subroutine foo
subroutine bar(f,v)
external f
integer v
call f(v)
end subroutine bar
program main
external foo
call bar(foo,42)
end program main
I will try this.
Many thanks for your support,
Detlef
Paul, sorry I have problems to understand the subroutine example.
This is my code, I want to run:
Main:
!***********************************************************************
PROGRAM DLL_TEST
!
IMPLICIT NONE
!-----------------------------------------------------------------------
CALL DLL
!
END
!***********************************************************************
SUBROUTINE MAINSUB(VAL)
!
IMPLICIT NONE
!
INTEGER*4 VAL
!-----------------------------------------------------------------------
PRINT*,'HELLO MAINSUB-WORLD',VAL
!
END
!***********************************************************************
DLL:
!***********************************************************************
SUBROUTINE DLL
!
IMPLICIT NONE
!
EXTERNAL MAINSUB
!-----------------------------------------------------------------------
PRINT*,'HELLO DLL-WORLD'
!
CALL DLLSUB(10)
!
CALL MAINSUB(20)
!
END
!***********************************************************************
SUBROUTINE DLLSUB(VAL)
!
IMPLICIT NONE
!
INTEGER*4 VAL
!-----------------------------------------------------------------------
PRINT*,'HELLO DLLSUB-WORLD',VAL
!
END
!***********************************************************************
My problem is to find a way to call subroutine MAINSUB from inside the DLL.
Detlef
!***********************************************************************
PROGRAM DLL_TEST
!
IMPLICIT NONE
EXTERNAL MAINSUB
!-----------------------------------------------------------------------
CALL DLL(MAINSUB)
!
END
!***********************************************************************
SUBROUTINE MAINSUB(VAL)
!
IMPLICIT NONE
!
INTEGER*4 VAL
!-----------------------------------------------------------------------
PRINT*,'HELLO MAINSUB-WORLD',VAL
!
END
!***********************************************************************
!***********************************************************************
SUBROUTINE DLL(SUB)
!
IMPLICIT NONE
!
EXTERNAL SUB
!-----------------------------------------------------------------------
PRINT*,'HELLO DLL-WORLD'
!
CALL DLLSUB(10)
!
CALL SUB(20)
!
END
!***********************************************************************
SUBROUTINE DLLSUB(VAL)
!
IMPLICIT NONE
!
INTEGER*4 VAL
!-----------------------------------------------------------------------
PRINT*,'HELLO DLLSUB-WORLD',VAL
!
END
!***********************************************************************
Thanks Paul, now I have understood. It's working as I want.
Detlef