- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to create and use a simple Fortran DLL butthat results in an error message
"R6034: An application has attempted to load the C runtime library incorrectly"
This is with Intel Fortran 11.1 on Windows XP.
Here are my compile and build commands:
ifort mydll.f90 -dll
ifort myprogram myprogram.f90 mydll.lib
and the code:
--- mydll.f90 ---
module prng_factory
implicit none
integer, parameter :: type_uniform = 1
integer, parameter :: type_exponential = 2
type, abstract :: prng
! No data
contains
procedure(get_next), deferred :: get
end type
abstract interface
real function get_next( params )
import :: prng
class(prng) :: params
end function get_next
end interface
type, extends(prng) :: prng_uniform
real :: xmin, xmax
contains
procedure :: get => get_uniform
end type
type, extends(prng) :: prng_exponential
real :: xmean
contains
procedure :: get => get_exponential
end type
contains
real function get_uniform( params )
!DEC$ attributes dllexport :: get_uniform
class(prng_uniform) :: params
real :: r
call random_number( r )
get_uniform = params%xmin + (params%xmax-params%xmin) * r
end function get_uniform
real function get_exponential( params )
!DEC$ attributes dllexport :: get_exponential
class(prng_exponential) :: params
real :: r
call random_number( r )
get_exponential = -params%xmean * log( r )
end function get_exponential
function prng_create( type, param1, param2 )
!DEC$ attributes dllexport :: prng_create
integer :: type
real :: param1
real, optional :: param2
class(prng), pointer :: prng_create
type(prng_uniform), pointer :: uniform
type(prng_exponential), pointer :: exponential
select case (type)
case (type_uniform)
allocate( uniform )
prng_create => uniform
case (type_exponential)
allocate( exponential )
prng_create => exponential
case default
nullify( prng_create )
end select
select type (prng_create)
type is (prng_uniform)
if ( present(param2) ) then
prng_create%xmin = param1
prng_create%xmax = param2
else
prng_create%xmin = 0.0
prng_create%xmax = param1
endif
type is (prng_exponential)
prng_create%xmean = param1
end select
end function prng_create
end module prng_factory
--- myprogram.f90 ---
program test_prng_factory
use prng_factory
class(prng), pointer :: p
integer :: i
p => prng_create( type_uniform, 1.0, 2.0 )
do i = 1,10
write(*,*) p%get()
enddo
p => prng_create( type_exponential, 10.0 )
do i = 1,10
write(*,*) p%get()
enddo
end program test_prng_factory
This works fine on Linux (using Intel Fortran 12) and with gfortran on Windows XP (but then
I do not have to worry about the DLLEXPORT stuff).
What am I doing wrong?
Regards,
Arjen
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
EIther you are using an earlier version than 11.1.070, or there is some problem with the configuration/environment.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I wil check further tomorrow.
Regards,
Arjen
- 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
Thanks! I will try that - that serves me right for avoiding the Visual Studio environment ;). But for such
small programs I find it a very heavy environment.
Regards,
Arjen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, that solved the problem! I removed the DLLEXPORT directives from the get_uniform and get_exponential functions and the program still worked. I guess these are not required, because they are resolved at run-time?
Regards,
Arjen
- 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
type-bound procedures in a DLL. I guess that getting back the object from an (exported)function/subroutine
in the DLL is enough to make these type-bound procedures available in the calling program. They are
not invoked directly from my program.
I see some interesting possibilities here (a "plugin archtecture").
Regards,
Arjen
- 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