- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can anyone suggest how to go about this I have a dll project that is launched by an exe. I created this example project below where the dcalc array has values and passes the array to one dll. Then the next dll has the array defined in a module.
At the point where the Dll_2_mod is called the values in the array are wiped out.
The end goal in the real project is a number of dll's will be adding to the dcalc array and I did not want to change arguments to pass the array because the project already has a module layout.
Sample code:
program Module_Pass_Array Real,dimension(10) :: Dcalc Do I=1,10 Dcalc(i) = real(i+1) Enddo Call dll_1(dcalc) end program Module_Pass_Array subroutine Dll_1(dcalc) !DEC$ ATTRIBUTES DLLEXPORT::Dll_1 Real, Dimension(10) :: Dcalc Call Dll_2_mod() end subroutine Dll_1 Module Module_dcalc !DEC$ ATTRIBUTES DLLEXPORT::Module_Decalc Real, dimension(10) :: Dcalc End Module subroutine Dll_2_mod Use Module_dcalc !DEC$ ATTRIBUTES DLLEXPORT::Dll_2_mod Write(*,'(A, F7.2)') 'Dcalc', dcalc(2) end subroutine Dll_2_mod
Thanks in advance for any help. Ken
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As supplied, this doesn't have a lot to do with DLL's. The Dcalc variable in Module_dcalc is unrelated to the Dcalc variable in the main program and the Dcalc variable in the Dll_1 subroutine (those two are linked by argument association). The Dcalc variable in Module_dcalc never has a value set and so is undefined - there is nothing to "wipe out".
It might be worth providing more explanation about what it is you are trying to achieve.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the comment. I was trying to make the variable associated by argument the same as in the module. This was for the reason I had an existing exe that lauched the project using the argument array. Then The dll's using a module I hope can maybe point to the initial memory. Perhaps using some sort of pointer allows the array in the module the same values as the exe array?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You need some way to explicitly associate Dcalc within the module Module_dcalc with the Dcalc that is in the main program. There are a couple of options, what's best depends on your specific situation. My view is that if you need to pass information to and from a procedure, then you explicitly pass that information to and from the procedure using arguments, but if you wanted to make the module variable a pointer, you could do something like this:
program Module_Pass_Array Implicit None Integer :: i Real,dimension(10) :: Dcalc Interface Subroutine Dll_1(dcalc) Implicit None Real, Dimension(10), Target :: Dcalc End Subroutine Dll_1 End Interface Do i=1,10 Dcalc(i) = real(i+1) Enddo Call dll_1(dcalc) end program Module_Pass_Array subroutine Dll_1(dcalc) Use Module_dcalc, Only: AssociateDcalc !DEC$ ATTRIBUTES DLLEXPORT::Dll_1 Real, Dimension(10), Target :: Dcalc Call AssociateDcalc(Dcalc) Call Dll_2_mod() end subroutine Dll_1 !------------------------------------------------------------------------------- Module Module_dcalc Implicit None Real, Pointer :: Dcalc(:) Contains Subroutine AssociateDcalc(remote) !DEC$ ATTRIBUTES DLLEXPORT :: AssociateDcalc Real, Target :: remote(:) Dcalc => remote End Subroutine End Module subroutine Dll_2_mod Use Module_dcalc Implicit None !DEC$ ATTRIBUTES DLLEXPORT::Dll_2_mod Write(*,'(A, F7.2)') 'Dcalc', dcalc(2) end subroutine Dll_2_mod
Note that with the above code, the association between the Dcalc that is the module variable and the dcalc that is the argument to the Dll_1 procedure only lasts as long as the invocation of the Dll_1 procedure. If you want the association to last longer than that, then you need to give the Dcalc in the main program the target attribute too. The use of the target attribute on procedure arguments necessitates an explicit interface, hence the interface block. This would be unnecessary if your procedures were declared within modules.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
IanH, I was able to get that to work with one exception.
I had to add an export like below; !DEC$ ATTRIBUTES DLLEXPORT :: Dcalc in the module.
Otherwise I would get a link error.
Module Module_dcalc Implicit None Real, Pointer :: Dcalc(:) !DEC$ ATTRIBUTES DLLEXPORT :: Dcalc Contains Subroutine AssociateDcalc(remote) !DEC$ ATTRIBUTES DLLEXPORT :: AssociateDcalc Real, Target :: remote(:) Dcalc => remote End Subroutine End Module
Zip attached if anyone needs as a reference.
Thanks for your help IanH.
Ken

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