Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28595 Discussions

Share data between two DLLs that are called by Main program

Alireza_Forghani
Beginner
1,228 Views

I work with a finite element software that allows user-defined functions loaded from DLLs, one DLL per each function. 

My two functions share the same module, but when turned into DLLs and loaded by the main program, data between is not shared between the two DLLs. 

Examples that I have seen, like here, are all about sharing data between DLLs and the main program. I was wondering if it is possible to share data between two DLLs that are called by the main program. 

And please note that the main program is a black box to me and I have no control over it. 

Thanks,

Alireza

 

0 Kudos
1 Solution
mecej4
Honored Contributor III
1,228 Views

You have to manage the exported symbols appropriately. Therefore, to Line-2, add "/export:SHARED_MOD_mp_GET /export:SHARED_MOD_mp_PUT".

Secondly, since we are using DLLs rather than static libraries, in Lines 4 and 8 use "sharedModule.lib", the name of the exports library produced in the previous step, and add "/export:SUBGET" or "/export:SUBPUT", respectively.

Finally, since the main program calls subroutines in SUBROUTINE1.DLL and SUBROUTINE2.DLL, in Line-11 add at the end "subroutine1.lib subroutine2.lib"

Note that no two .OBJ files in this test project are ever linked together, because that would be static linking.

View solution in original post

0 Kudos
7 Replies
mecej4
Honored Contributor III
1,228 Views

It is possible, if complicated, to share data between DLLs, and you can search this forum for several posts about how that can be done. There are also examples in the IFort distribution, in samples/en_US/Fortran/MixedLanguage.zip.

Consider a cleaner alternative which is easier to build and safer to run, provided  the amount of shared data is small and the number of reads and writes of that data is moderate.

Suppose we call the two DLLs that your FEA software calls as DLL-A and DLL-B. You build a third, DLL-C, which holds (hoards?) and manages the shared data, and provides get() and put() subroutines for storing and retrieving the shared data. In DLL-A and DLL-B, you call the get() and put() routines of DLL-C whenever you want to access the shared data.

If this approach appears satisfactory for your purposes, I can provide sample code and instructions to help you get started.

0 Kudos
Alireza_Forghani
Beginner
1,228 Views

Thanks for the response. 

My two subroutines, share the same module that defines common functions and subroutines, complex data structure types, and also holds data. Due to its complex data structure, I'm not sure if get() put() would be an easy solution. 

Now if we can put the this shared module in a DLL (your DLL-C),  and somehow both DLL-A and DLL-B share the data in DLL-C, the problem will be solved. 

Would appreciate it if you could send me more info and examples. 

 

0 Kudos
mecej4
Honored Contributor III
1,228 Views

Presumably, the FEA program calls one or more subroutines/functions in DLL-A and DLL-B, using only argument lists to exchange data. In turn, DLL-A and DLL-B make calls to subprograms in DLL-C, again solely through argument lists. DLL-C can contain any number of private subprograms, and all the shared data can be kept in modules or common blocks in the DLL. The subprograms in DLL-C have full access to the shared data. DLLs A and B, on the other hand, by design, have no access to the shared data.

Sample code for DLL-C:

module shared_mod
integer,private :: sh_integer

contains
  subroutine put(ival)
  integer, intent(in) :: ival
  sh_integer=ival
  return
  end subroutine put

  subroutine get(ival)
  integer, intent(out) :: ival
  ival=sh_integer
  return
  end subroutine get

end module shared_mod

Code for DLL-A:

subroutine subget(v)
integer, intent(out) :: v
interface
  subroutine shared_mod_get(i)  bind(C, name = 'SHARED_MOD_mp_GET')
  integer, intent(out) :: i
  end subroutine shared_mod_get
end interface
call shared_mod_get(v)
return
end

and, for DLL-B:

subroutine subput(v)
integer, intent(in) :: v
interface
  subroutine shared_mod_put(i)  bind(C, name = 'SHARED_MOD_mp_PUT')
  integer, intent(in) :: i
  end subroutine shared_mod_put
end interface
call SHARED_MOD_PUT(v)
return
end

Finally, a test program, which takes the place of your FEA program.

program getput
implicit none
integer i,j,k
do i=1,10
   j=i*i-1
   if(mod(i,2).eq.0)then
      call subget(k)
      write(*,*)'i,get(k) : ',i,k
   else
      call subput(j)
      write(*,*)'i,put(j) : ',i,j
   endif
end do
end program getput

 

0 Kudos
Alireza_Forghani
Beginner
1,228 Views

I tried the code and compiled/linked it using attached script. Compilation of main.f90 gives an error saying SUBGET and SUBPUT are not defined. Now if I define them as external, I would need to include all the objects to link them statically. 

 

ifort -traceback -c sharedModule.f90
link /dll /out:sharedModule.dll sharedModule.obj 
ifort -traceback -I .\ -c subroutine1.f90
link /dll /out:subroutine1.dll subroutine1.obj sharedModule.obj
rem link /dll /out:subroutine1.dll subroutine1.obj 

ifort -traceback -I .\ -c subroutine2.f90
link /dll /out:subroutine2.dll subroutine2.obj sharedModule.obj
rem link /dll /out:subroutine2.dll subroutine2.obj 

ifort -traceback main.f90

 

0 Kudos
mecej4
Honored Contributor III
1,229 Views

You have to manage the exported symbols appropriately. Therefore, to Line-2, add "/export:SHARED_MOD_mp_GET /export:SHARED_MOD_mp_PUT".

Secondly, since we are using DLLs rather than static libraries, in Lines 4 and 8 use "sharedModule.lib", the name of the exports library produced in the previous step, and add "/export:SUBGET" or "/export:SUBPUT", respectively.

Finally, since the main program calls subroutines in SUBROUTINE1.DLL and SUBROUTINE2.DLL, in Line-11 add at the end "subroutine1.lib subroutine2.lib"

Note that no two .OBJ files in this test project are ever linked together, because that would be static linking.

0 Kudos
Alireza_Forghani
Beginner
1,228 Views

Thanks very much, mecej4. it works now. 

0 Kudos
mecej4
Honored Contributor III
1,228 Views

Alireza F. wrote:

Thanks very much, mecej4. it works now. 

Good! Now you can try the idea with your FEA package. Make sure not to store any global data in Subroutine-1 or Subroutine-2.

0 Kudos
Reply