- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I want to build a Fortran DLL which includesan exported subroutine. The subroutine uses a module, which contains public dataarrays. Like this ...
module amodule
implicit none
public ::setupdata
character, dimension(40), public :: chdata
contains
subroutine setupdata
integer :: i
do i=1, 40
chdata(i) = "T"
end do
return
end subroutine
end module amodule
subroutine dllsub0
use amodule
implicit none
!DEC$ ATTRIBUTES DLLEXPORT::dllsub0
call setupdata
return
end subroutine
subroutine dllsub1(exdata)
use amodule
implicit none
character, dimension(40) :: exdata
!DEC$ ATTRIBUTES DLLEXPORT::dllsub1
integer :: i
do i=1, 40
exdata(i) = chdata(i)
end do
return
end subroutine
Compiling to a DLL and loading from e.g. VC++ works fine.I can also call the subs dllsub0 and dllsub1,and step into them using the debugger. Now after transfering the first character data from chdata(1) to exdata(1) in dllsub1, an access violation is caused somewhere. I can't figure out where. I also tried to access the module data viaan extra module subroutine, butencountered the same access violation again.
How can I get rid of it?
What can I do to get access to the module data?
Best regards
Juri
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't fully understand what you're asking. A complete example would be helpful, including the C source. In particular, you need to pass the character length from C to Fortran unless you add an ATTRIBUTES REFERENCE directive for exdata in dllsub1.
What do you mean by "tried to access the module data"? From where?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The problem is not the (C++)-(F90) interface. The problem appears within the dll fortran code. I have passed all variables from C++ to F90 by reference (set-up via project properties),this alsoapplies to the character arrays.All references work, i.e. the debugger gets the correct adresses. I alsocan manipulate the dummy arguments passed tofrom C++ to the F90-dllusing static data, e.g. exdata='Some data'works fine in dllsub1.
> What do you mean by "tried to access the module data"? From where?
The access violation is caused when a fortran routine in the dll accesses fortran module data, like exdata(i) = chdata(i) insubroutine dllsub1, even if the module data is accessed via subroutines contained by the module, which is somewhat mysterious in my eyes. This violation even occurs when no dummy argument passed from C++ is involved, i.e. an access violation is also caused with the following sub:
subroutine dllsub2()
use amodule
implicit none
!DEC$ ATTRIBUTES DLLEXPORT::dllsub2
character, dimension(40) :: nodummychars
integer :: i
do i=1, 40
nodummychars(i) = chdata(i) ! ... where chdata is module data
end do
return
end subroutine
I hope this claryfiesmy problem.
Best Regards
Juri
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In order to get your DLL to export the symbols correctly,
I found I had to move the DLLEXPORT directives to where
they are shown below, otherwise all I got when I did a
DUMPBIN was DLLMODULE as the exported symbol
(I also added the REFERENCE and ALIAS directives as shown)
(P.S. Note that in your code you defined 'MODULE A' then used 'USE AMODULE',
which cannot be correct surely? so I changed it to 'USE A'):
! dllmodule.f90
!
! FUNCTIONS/SUBROUTINES exported from dllmodule.dll:
!dllsub0 - subroutine
!dllsub1 - subroutine
!
module a
implicit none
public ::setupdata
character, dimension(40), public :: chdata
contains
subroutine setupdata
integer :: i
do i=1, 40
chdata(i) = "T"
end do
return
end subroutine
end module a
subroutine dllsub0
!DEC$ ATTRIBUTES DLLEXPORT::DLLSUB0
!DEC$ ATTRIBUTES C, REFERENCE, ALIAS:'DLLSUB0' ::dllsub0
use a
implicit none
call setupdata
return
end subroutine
subroutine dllsub1(exdata)
!DEC$ ATTRIBUTES DLLEXPORT::DLLSUB1
!DEC$ ATTRIBUTES C, REFERENCE, ALIAS:'DLLSUB1' ::dllsub1
use a
implicit none
character, dimension(40) :: exdata
integer :: i
do i=1, 40
exdata(i) = chdata(i)
end do
return
end subroutine
I then created a simple 'hello worl' console project shown belowto test the calls to the DLL routines, after adding the DLLMODULE.LIB, created when the DLL was created, to the project and DLLMODULE.DLL to that project's directory. When compiled and run, I got the output shown in the attached image:
! testdll.f90
program testdll
implicit none
interface
SUBROUTINE DLLSUB0()
!DEC$ ATTRIBUTES DLLIMPORT::DLLSUB0
!DEC$ ATTRIBUTES C, REFERENCE, ALIAS:'DLLSUB0'::dllsub0
END SUBROUTINE
END INTERFACE
INTERFACE
SUBROUTINE DLLSUB1(EXDATA)
!DEC$ ATTRIBUTES DLLIMPORT::DLLSUB1
!DEC$ ATTRIBUTES C, REFERENCE, ALIAS:'DLLSUB1' ::dllsub1
!DEC$ ATTRIBUTES REFERENCE :: EXDATA
character, dimension(40) :: exdata
END SUBROUTINE
END INTERFACE
character, dimension(40) :: exdata
print *, 'Hello World'
call DLLSUB0
call DLLSUB1(exdata)
print *, exdata
end program testdll
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, in this test project it works now.

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