- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
i have a problem sharing module between dll and main program
there are 2 sub programs in dll
1) chf_cor
2) module main_data
subroutine chf_cor (i, chf, correlation)
!
! Subroutine to evaluate chf using 1 of 9 different correlations
!
use main_data
!
implicit none
!
!dec$ attributes dllexport :: chf_cor
!
character(*) correlation
integer(4) i
real(8) chf
!
character(50) correlation_name(10)
!
real(8) constants(10)
!
data correlation_name(1) / 'chf correlation 0 - bur & wub ' /
!
data constants / 1.0d0, 2.0d0, 3.0d0, 4.0d0, 5.0d0, 6.0d0, 7.0d0, 8.0d0, 9.0d0, 10.0d0 /
!
num_cor = 10
write(6,*) 'num_cor = ', num_cor
chf = constants(i)*prop(i)
correlation = correlation_name(i)
!
end subroutine chf_cor
module
module main_data
!
!dec$ attributes dllexport :: num_cor
!
integer(4), save :: num_cor
!
!
real(8), save :: prop(10)
!
end module main_data
i did compile and created dll with following command
ifort /dll chf_cor.f90 main_data.f90
this created chf_cor.lib
the main program using dll looks like this
program main
use main_data
!
implicit none
!
integer(4) i
real(8) chf
character(50) correlation
!
i = 1
! num_cor = 10
call chf_cor (i, chf, correlation) ! this call initializes num_cor
!
write(6,*) 'num_cor = ', num_cor
do i = 1,10
prop(i) = i*1.0d0
end do
!
do i = 1, num_cor
!
call chf_cor (i, chf, correlation)
!
write (6,9000) i, chf, correlation
end do
!
9000 format ('numb = ',i2,' chf = ',1p,
e13.5,3x,a50)
end program main
the problem starts now
when i try to link .lib with main.f90
ifort /libs:dll main.f90 chf_cor.lib
i get an error saying liking error - unresolved external symbol referenced in program main
how do i resolve this ?
the only i way i can link if i use modules main_data.f90 again in main program
ifort /libs:dll main.f90 main_data.f90 chf_cor.lib
the only problem with this is the data in module is not sharable and does not reflect changes made by dll program in main program
help needed
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You should include INTERFACE blocks for all routines imported from your DLL (chf_cor being the only one visible in your code). These blocks should contain DLLIMPORT attributes for the symbols imported from the DLL so that thelinker knows where to find them.
If you have created CHF_COR.DLL and its accompanying export library CHF_COR.LIB, then add CHF_COR.LIB to your MAIN program solution. This should ensure the DLL is found and included when external references are satisfied. You still need to specify DLLIMPORT for the CHF_COR subprogram. Also, make sure that CHF_COR.DLL is copied to a location where the MAIN program can find it (into the same directory as the MAIN.EXE for example)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thanks for the prompt reply
this works ok, i have another problem with the same program
i am trying to share character data of module between dll and main program
as i understand it creates two copies of data objects.
i declared !DEC$ ATTRIBUTES DLLEXPORT :: ibaw2 in one of the modules shared by dll and main program
when main program starts evene before initializing ibaw2 - it gets some garbage values XD00, also it does not allow it to be over written by any subroutine.
when try to access ibaw2 in dll subroutine it still has the same garbage value.
without import/export the value is blank
help needed
thanks in advance
- 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
i can not find the sample code
can you send it again
thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
C:Program FilesIntelCompilerFortran10.1.024samplesDLLDLL_Shared_Data
This particular sample uses a single DLL whose variables are write-shared among two separate executables. This may be a bit more complex than you need, but the basic principles are similar as to how you declare things. If you're not sharing data among programs, just within a single program, then you don't need the linker option for read-write sharing.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
The example you reference indicates that the variables in the module to be shared must be initialized:
real
:: shared_variable = 999.0 ! Must initialize to non-zero value ! in order to be placed in .data sectionI am trying to share an allocatable array,which is in a module, between a main program and a DLL. For instance:
MODULE KMODELT INTEGER, ALLOCATABLE :: MODID(:) !DEC$ ATTRIBUTES DLLEXPORT :: MODID ENDMODULE KMODELTI cannot initialize MODID as it is allocatable. So, is there a way to share a allocatable array in a modulein a DLL?
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
An ALLOCATABLE array does not require anything special to be shared across EXEs in a DLL. A POINTER should be initialized to NULL() if shared.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve,
No, I am just running one executable. I am trying to be able to access the MODID(:) array in the DLL via a USE statement.MODID has been allocated and assigned values in the the main program. When I call the subroutine that is part of the DLL, it seems not to know that the array has been allocated, and I get the error:
forrtl: severe (408): fort: (2): Subscript #1 of the array MODID has value 1 which is greater than the upper bound of -1
So, in my case, with just one executable, do I not need the /section:data,RWS liner command line directive?
Is there something else I need to do to be able to access the array in the DLL? Maybe a DLLIMPORT directive in the subroutine within the DLL?
Thanks for your help.
Brett Bednarcyk
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>An ALLOCATABLE array does not require anything special to be shared across EXEs in a DLL.
!!???!!
Explain please why if the array descriptor "lives" in the DLL address space .AND. if one EXE of potentially several EXE's issues an allocate then how does the descriptor point globally (to all DLL users) allocated memory as opposed to memory within the EXE that performed the allocation?
It would seem like you would want to export the array descriptor in the EXE and import it (in EXE context) into the DLL. The the allocations are local to the EXE by visible to the DLL on an EXE by EXE basis. (each EXE has seperate area of memory with same name in DLL)
Alternately, with descriptor inside DLL you could perform a call from the EXE to the DLL with instructions to allocate memory from a pool mapable inside the DLL while addressable from EXE's using the DLL copy of the descriptor. This would not be a standard allocate as it would require specifying a seperate heap (one that grows in the DLL). (shared memory)
If you want shared memory amongst several processes consider using a memory mapped file from within the EXE and building descriptors to the memory mapped file. The function to perform this would be in the DLL. In this manner, each application gets its own array descriptor pointing at the same memory mapped file but which may reside at different virtual addresses within each process. If the process dies the processes handle(s) to the memory mapped file are closed and things are cleaned up. If you hack something into a common array descriptor inside the DLL you would not get this cleanup capability.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Apparently I do not know how to make any data in a module accessible in a DLL as I just changed things to try to access a REAL rather than the allocatable array and it did not work either - the value is wrong inside the DLL. Perhaps you could just outline how to access data in a module through the USE statement in a DLL, or point me to where I can find this.
One note - I have the module code in both the main program and the DLL projects - is this wrong? I needed to do this in order to get the DLL to link.
Thanks,
Brett
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The module source belongs in the DLL project. Add ATTRIBUTES DLLEXPORT directives for any items you want exported.
For the executable project, add the "output" folder of the DLL project (the Debug or Release) folder to the list of INCLUDE folders. Add a USE of the module to the executable project sources. It will pick up the .mod file from the DLL project.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve:
I have a similar problem, and I try to do what you suggest. However, still I am doing something wrong.
I have a Fortran EXE and a Fortran DLL. I need to access allocatable arrays from both. I wrote this module:
MODULE MODFLOW_GLOBAL
INTEGER, ALLOCATABLE, DIMENSION(:) :: MFL_COL
INTEGER, ALLOCATABLE, DIMENSION(:) :: MFL_ROW
CHARACTER(200) :: MFL_FILENAME
!DEC$ ATTRIBUTES DLLEXPORT :: MFL_COL, MFL_ROW
!DEC$ ATTRIBUTES DLLEXPORT :: MFL_FILENAME
END MODULE MODFLOW_GLOBAL
That I added as part of the DLL project. I then have the include directory where the correspoding MOD is in the EXE file.
I read the character variable in the EXE and allocate the arrays, butitis notright. THe values are not correct.
Couldyou help?
Thanks
Reinaldo
- 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
Steve,
Thank you for your excellent help - things seem to be working for me now.
I have a couple more quick questions that I hope you can answer:
1) Do the modules have to be in the DLL project? Is it not possible to put them in the EXE project and, within the DLL project,get the .mod files through the INCLUDE directory specification?
2) Is there a way to make all variables in a file or a module default to ATTRIBUTES DLLEXPORT without having to explicitly type the directive for each variable? I have hundreds of modules with thousands of variables, and it would help a lot to have short cut like this.
Thanks,
-----Brett
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2) No. We have a wish-list item for this and I will add your request to it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Brett,
<
You could encapsulate the variables in a moduleinto a user declared type and create one instance of that type which is exported.
module mod_foo
type Type_mod_foo
real :: A,B,C
...
end Type_mod_foo
cDEC$ ATTRIBUTES DLLEXPORT :: FOO
type(Type_mod_foo) :: FOO
However, this will require you to specify the container when referencing the variables
FOO%A
This can be hidden using the preprocessor FPP
#define A FOO%a
#defineB FOO%b
place the above in an include file that is not part of the module and is included in your source files.
But then debugging is a bit awkward (intellipoint won't work and you have to watch FOO%A instead of A)
Steve,
Can you look at extending the USE mapping capability to map fields of declared defined types to local variables
use mod_foo, FOO%A => A
Then a user such as Brett could accomplish the mapping with an ugly Fortran include file.
Alternately, extend EQUIVALENCE to accept a similar syntax (take plenty of barf bags to the next committee meeting when you suggest this).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What you're asking for is sort of like the ASSOCIATE construct in F2003. The syntax looks like this:
ASSOCIATE (A => FOO%A)
... do things with A that are really FOO%A
END ASSOCIATE
Intel Fortran 10.1 does not support this, but it will come in the next major release, whenever that is....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tried building the DLL in CVF rather than ifort, and it compiled and linked, but it is not running correctly when calling it from the ifort EXE project - I am getting an error about allocating an array that has already been allocated. This is with everything the same, only now building the DLL with CVF. I am using the CVF calling convention in the ifort projects. Also, because the subroutine in the DLL calls subroutines in the EXE, I had exposed these subroutines in the EXE with DLLEXPORT and included the resulting .LIB in the DLL project. As I said,this worked for the ifort DLL.Could this .LIB be the problem, or maybe the .MODS now being generated by the CVF DLL project? Or should this work and maybe I have an alignment issue or something screwing up the memory?
Thanks,
----Brett
- 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