Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sharing data between functions when using Fortran DLLs

Status
Not open for further replies.

NickFort

Technical User
Jun 10, 2010
113
Hi,

I'm currently starting work on an engineering package that's calculations will be done with Fortran 95, with a GUI in Delphi (or to be more accurate, Lazarus:
Before I start any coding, I've been working on a "battle plan" for this thing. I'd like to split the program into DLLs, which can either call each other, or be called from the GUI. I've found excellent examples on this forum for creating DLLs with gfortran:


and a resource for a Fortran-Delphi interface:
So, I suspect that I'll manage to pull that part off; if not, I'll be back here bugging you guys. ;)

But now, here's where my confusion comes in: what's the best way to share data between those DLLs, other than passing giant arrays from one function to the next? I imagine that would result in unnecessary overhead, although I could be mistaken. You see, in the GUI, I plan to load a pretty big matrix of data, from which only a subset will be used throughout the various Fortran DLLs. The idea I have is to load the required data into memory somewhere, and then have each Fortran function pick and take from that data set as it requires.

Forgetting the GUI bit for now, let's assume that everything is being done in Fortran, to make this discussion a bit simpler.

There are three options that spring to mind:

(1) modules,
(2) pointers, and
(3) persistent variables (not sure if that's the right term)

For option (1), I can't see how this might work without values having to be hard-coded. For option (2), well, I have no idea how to implement pointers (and only a rudimentary idea of what they do), but they sound like they might do what I need; if so, I'll have a good deal of reading to do. For (3), what I mean by "persistent" is using the SAVE parameter in a function, and writing to or reading from it as required. I suspect that (3) would work, but it doesn't seem much better than passing these huge arrays from one function to the next.

What would you guys suggest as the most efficient and elegant solution to this problem?

Thanks!
NickFort

--------------------------------------
Background: Chemical engineer, familiar mostly with MATLAB, but now branching out into real programming.
 
1) Which compiler are you using? How you code DLLs depends on which compiler you're using

2) There are two ways of sharing memory on Windows. One way is using the memory mapping using the kernel DLL. The other way is to use a named data segment.
 
Sorry - jusr reread your original. You're using gfortran. In that case, you'd be better off using the kernel DLL.

Back to your question - is this data that you're passing around used in one or several DLLs? If one DLL, I'd go for a module level implementation because

1) you don't have to declare it again - just use the module
2) it is global within the module
3) if you ever change the dimensions of the array, you only need to change it once

You can use pointers or the array itself. The problem is the age old one of global variables versus parameter passing. You can use parameter passing if you think it is easier to understand and there is no speed problem.

Not sure how save variables come into it. Save variables will only work within each routine. Local variables declared in the routine will remember their values on exit. If it is a massive array, I'm can't see how that is going to help.
 
Thanks for the reply, xwb!

Regarding point (2) in your first post, is there a way of making it portable to other OSs? I'd like to be able to compile this on Linux as well at some stage (although that really isn't too big a deal if it's a mission to implement). Are either of those options for DLLs (or SOs in Linux, am I right?) fairly easy to compile on Linux with few/no modifications to the code?

I have no idea what either memory mapping using the kernel DLL or named data segments are, but Google, here I come! :) I'll post more on this if my investigation leaves me confused.

To answer your question, the data would be used in several DLLs, which could be used at any time while the package (GUI included) is running. So, for example, when the GUI is started up, the user chooses a required data set, and can then perform various operations using that data set with the DLLs.

The module approach would be my first choice as well, BUT, what I don't understand is how to have a module contain the data I want, without the values being hard-coded and compiled, such that the data set used is a user choice. I could get the module to read data from a file, I guess, but would that not result in a read-from-disk operation every time a sequence of DLLs is called by the GUI? From a speed point of view, I imagine that keeping the data in RAM would be preferable.

Regarding save variables, what I did in the past was have a subroutine that you could write data into, or read from it. So, for example, you would pass a string "r" or "w" as the last parameter, telling it whether to read or write data to some internal array. Here's an example of some code I used when I first started fiddling with Fortran last year:

Code:
SUBROUTINE sendparams(R_Delta, X_Delta, Delta, act)

IMPLICIT NONE

DOUBLE PRECISION, INTENT(INOUT) :: R_Delta
DOUBLE PRECISION, INTENT(INOUT) :: Delta
DOUBLE PRECISION, DIMENSION(2), INTENT(INOUT) :: X_Delta
CHARACTER(len=1), INTENT(IN) :: act

DOUBLE PRECISION, SAVE :: R_Delta_internal
DOUBLE PRECISION, DIMENSION(2), SAVE :: X_Delta_internal
DOUBLE PRECISION, SAVE :: Delta_internal

IF (act=='w') THEN
	R_Delta_internal = R_Delta
	X_Delta_internal = X_Delta
	Delta_internal = Delta
ELSEIF (act=='r') THEN
	R_Delta = R_Delta_internal
	X_Delta = X_Delta_internal
	Delta = Delta_internal
END IF
	
END SUBROUTINE

I'm not convinced that that would work for DLLs anyway.

"The problem is the age old one of global variables versus parameter passing." What's the age-old conclusion? ;) I know that in MATLAB it slows things down a good deal, but MATLAB isn't compiled, so I would expect that it's a different ball-game altogether.

I hope that made sense; if not, tell me and I'll try to clarify. :)

--------------------------------------
Background: Chemical engineer, familiar mostly with MATLAB, but now branching out into real programming.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top