INTERNAL: IDL Callable console application written with PASCAL/DELPHI
Help Article Update 2
Anonym
Update 1/21/2013 : I think that this could be a decent example of how to translate a PASCAL program to IDL if this is necessary. Perhaps, it will come in handy. Leaving internal.
Topic:
Customer had a PV-WAVE cwavec program written in PASCAL. They wanted to convert this code to use IDL Callable so they can switch to IDL. Note that although the customer was interested in eventually using ActiveX, initially they only wanted to convert their existing console application.
Discussion:
Original Code:
program Project1;
// Test program (in Delphi 3 under WindowsNT) to call PV-Wave
// M Bennett, DERA, Farnborough, Hants - 9 July 1998
// Fixed by Brian Long (using cwavec rather than cwavefor)
// stdcall -cdecl, subsequently
{$APPTYPE CONSOLE}
uses
dialogs, sysutils ;
//N.B. Set a DOS env. var. VNI_DIR to point to the base PV_WAVE directory.
//Really the PV_Wave installation should do that, but never mind
//In AUTOEXEC.BAT, something like:
// SET VNI_DIR=D:\VNI
FUNCTION cwavec(action:integer; numcmd:integer; ptr: pointer):integer; cdecl; external 'vniwave.dll';
// Note: PV-Wave is a console application which, when used interactively, responds
// to commands which normally result in display of a graph in a second window {$R *.RES}
const
var
Cmds : array[0..NumCmds-1] of PChar;
istat : integer; { status flag }
PascalString: String;
CString: array[0..255] of Char;
begin
writeln('display some text');
readln;
{ define commands }
//No memory allocation required for literal strings...
/// cmds[0] := 'PRINT, 999';
cmds[0] := 'a = INDGEN(5) * 4';
cmds[1] := 'b = a # a';
cmds[2] := 'PRINT, b';
cmds[3] := 'SURFACE, b';
cmds[4] := 'WAIT, 5.0';
cmds[5] := 'PLOT, a';
//Careful memory set up required if not using literal strings
//You need a c-string buffer (zero-based character array), and a call to StrPCopy
PascalString := 'WAIT, 3.0';
StrPCopy(CString, PascalString);
cmds[6] := CString;
{ call WAVE }
istat := 666;
try
istat := cwavec (2, NumCmds, @cmds);
except
ShowMessage('istat ='+ intToStr(istat));
end;
// ShowMessage('action istat ='+ intToStr(istat));
{ close WAVE session - change action from 2 to 3 }
WriteLn('Press Enter to continue...');
readln;
istat := 666;
try
istat := cwavec (3, 0, nil );
except
ShowMessage('istat ='+ intToStr(istat));
end;
// ShowMessage('close istat ='+ intToStr(istat));
WriteLn('Press Enter to terminate...');
readln;
end.
Solution:
program Project1;
// Test Program in Delphi (in Delphi 3 under Window NT) to call IDL
// Written By: M Bennett, DERA, Farnborough, Hants 9 July 1998
// Updated By: Jaye Lampe, Research Systems, Inc. 1 October 1998
// Uses IDL Callable, in console mode
// Disclaimer: I'm not a Pascal programmer, so there are most certainly
// some elements of the portions of the example that
// I have added that could be redone to be more correct for Pascal. -JRL
{$APPTYPE CONSOLE}
uses
dialogs, sysutils ;
// Create Function prototypes for Callable IDL
FUNCTION IDL_Win32Init(iOpts:integer; hinstExe:pointer; hwndExe:pointer; hAccel:pointer):integer;cdecl;external 'idl32.dll';
FUNCTION IDL_Execute(argc:integer; argv:pointer):integer;cdecl;external 'idl32.dll';
FUNCTION IDL_ExecuteStr(cmd:string):integer;cdecl;external 'idl32.dll';
FUNCTION IDL_Cleanup(just_cleanup:integer):integer;cdecl;external 'idl32.dll';
{$R *.RES}
const
NumCmds = 7;
var
Cmds:array[0..NumCmds-1] of PChar;
istat:integer; { status flag }
PascalString:String;
CString:array[0..255] of char;
hinst, hwind, accel:pointer;
begin
writeln('display some text');
readln;
// No memory allocation required for literal strings
Cmds[0]:='a=indgen(5) * 4';
Cmds[1]:='b=a#a';
Cmds[2]:='PRINT,b';
Cmds[3]:='SURFACE,b';
Cmds[4]:='WAIT,5.0';
Cmds[5]:='PLOT,a';
// Careful Memory set up required if not using literal strings
// You need a c-string buffer (zero-based character array), and a call
// to StrPCopy
PascalString :='Wait, 3.0';
StrPCopy (CString, PascalString);
Cmds[6]:=CString;
// Initialize IDL
try
istat := IDL_Win32Init(0, hinst, hwind, accel);
except
ShowMessage('istat on init ='+intToStr(istat));
end;
// Send down the IDL command array
try
istat := IDL_Execute(NumCmds, @Cmds);
except
ShowMessage('istat on Execute ='+intToStr(istat));
end;
// Here's how you can send down single IDL commands:
//try
// istat := IDL_ExecuteStr('Plot, Indgen(10)');
//except
// ShowMessage('istat on Execute ='+intToStr(istat));
//end;
// IDL_Cleanup (replaces calling cwavec with 'mode' 3)
// If you call IDL_Cleanup with 0 instead of 1, it will kill the app for you.
try
istat := IDL_Cleanup(1);
except
ShowMessage('istat on Cleanup ='+intToStr(istat));
end;
// Allow user to exit console application
WriteLn('Press Enter to Terminate...');
readln;
end.