vensim_get_val called from Delphi

Use this forum to post Vensim related questions.
Post Reply
PeterB
Junior Member
Posts: 11
Joined: Fri Apr 04, 2008 1:28 pm

vensim_get_val called from Delphi

Post by PeterB »

Dear colleagues,

when trying to get variable values from an ongoing vensim simulation into a Delphi 5.0-coded application I can't make the function vensim_get_val() work. However, after simulation it's easy to access the same variables with vensim_get_data().

To be more precise, here are the relevant Delphi code fragments:



// global type and variable definitions

type
TSingleTimeline = array[1..2000] of Single;

var
SumSubstrateHeight: TSingleTimeLine;
timeval: TSingleTimeline;



// procedures

procedure A;
var result: Integer;
begin
result := vensim_command('SIMULATE>RUNNAME|Current');
result := vensim_command('MENU>RUN|O');
result := vensim_get_data('Current', 'Sum Substrate Height', 'Time',
@SumSubstrateHeight[1], @timeval[1], 2000);

end;


procedure B;
var result, i: Integer;
CurrentTime, CurrentValue: Single;

begin
result := vensim_command('SIMULATE>RUNNAME|Current');
result := vensim_start_simulation(1,0,1);
if result = 1 then begin
while result = 1 do begin
i := vensim_get_val('Time', @CurrentTime);
i := vensim_get_val('Sum Substrate Height', @CurrentValue);
result := vensim_continue_simulation(20);
end;
result := vensim_finish_simulation();
end;
end;



While procedure A works perfectly, procedure B fails completely. When coming into the while-loop for the first time vensim_get_val() returns 0. At the second time the computer hangs or reports an access violation message. Can anybody tell me where the mistake is in procedure B?

Greetings
Peter
bob@vensim.com
Senior Member
Posts: 1107
Joined: Wed Mar 12, 2003 2:46 pm

Post by bob@vensim.com »

Hi Peter,

It does not look like anything is wrong to me - though you might try making the values vectors of length 1 and passing the first element.

Are you using version 5.7a?
PeterB
Junior Member
Posts: 11
Joined: Fri Apr 04, 2008 1:28 pm

Post by PeterB »

Hi Bob,

thanks for your quick reply. I tried and changed procedure B into this form:



procedure B;
var result, i: Integer;
CurrentTime, CurrentValue: array[1..1] of Single;

begin
result := vensim_command('SIMULATE>RUNNAME|Current');
result := vensim_start_simulation(1,0,1);
if result = 1 then begin
while result = 1 do begin
i := vensim_get_val('Time', @CurrentTime[1]);
i := vensim_get_val('Sum Substrate Height', @CurrentValue[1]);
result := vensim_continue_simulation(20);
end;
result := vensim_finish_simulation();
end;
end;


However, the problem remains the same. In detail, it looks like this: When I call procedure B without placing breakpoints in there, simulation starts, but Delphi/Windows quickly reports an access violation in module vendll32.dll. When I call procedure B after that again, I get a message dialog (Caption: 'Vensim Program Error') which reads 'sim/init_vec1' (I guess this is the consequence of the abnormally terminated simulation before?).
After deactivating the vensim_get_val() calls, procedure B produces a smooth simulation run.

I think, It can't be a flaw in the model itself. Started directly in the Vensim environment as well as called from procedure A it always behaves dutifully and numerically stable. There are no stochastical elements in it. Its main structure is a 20x20 two-dimensional array of levels which are interlinked vertically, horizontally, and diagonally by rates.

Do you have an idea what it could be? I can work with a procedure A-like construction, no problem, but in some cases I would be happier with something like procedure B.

Best greetings
Peter

P.S. I'm using Vensim Version 5.7a.
bob@vensim.com
Senior Member
Posts: 1107
Joined: Wed Mar 12, 2003 2:46 pm

Post by bob@vensim.com »

Hi Peter,

A couple of things to check.

First, check the declaration of vensim_get_val to be sure it is the same as it is for other - I just checked and it is declared far instead of stdcall in the sample that ships with Vensim - that might be the source of the problem.

Second, try running the procedure without the vensim_get_val calls then look at the resulting vdf file in regular Vensim to be sure it OK (assuming this works).
PeterB
Junior Member
Posts: 11
Joined: Fri Apr 04, 2008 1:28 pm

Post by PeterB »

Hi Bob,

thanks a lot! Using the following declaration (with 'stdcall' instead of 'far') did the trick:

function vensim_get_val(varname:PChar; varvals: SinglePtr): Integer ; stdcall ; external 'vendll32.dll' ;

vensim_get_val() now works in both versions of procedure B.

Greetings
Peter
Post Reply