Share data between two DLLs that are called by Main program

Share data between two DLLs that are called by Main program

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

 

8 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

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.

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. 

 

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

 

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

 

Best Reply

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.

Thanks very much, mecej4. it works now. 

Quote:

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.

Leave a Comment

Please sign in to add a comment. Not a member? Join today