Search code examples
delphipascalscript

Pascal Script, how to return var parameter from script into my Delphi code?


I need to modify function parameter variable (string) in my Pascal Script code and get it in the Delphi function, after the script finish it's work.

My script code:

function OnBroadcastMessage(iCID, iUIN: integer; var sUsersList: string; dtActualTo: double; bMustRead, bReadNotify: boolean; sMsg: string): boolean;
begin
  sUsersList := '3';
  result := true;
end;

begin

end.

My Delphi XE3 code (only tiny example, without any checks):

var
  Compiler: TPSPascalCompiler;
  Exec: TPSExec;
  ProcNo: cardinal;
  ParamList: TIfList;
  Data: AnsiString;
begin
  Compiler := TPSPascalCompiler.Create;
  Compiler.Compile(Script)
  Compiler.GetOutput(Data); 
  Compiler.Free;

  Exec.LoadData(Data);

  ProcNo := Exec.GetProc('OnBroadcastMessage');
  ParamList := TIfList.Create;

  ParamList.Add(@iCID);
  ParamList.Add(@iUIN);
  ParamList.Add(@sUsersList);
  ParamList.Add(@dtActualTo);
  ParamList.Add(@bMustRead);
  ParamList.Add(@bReadNotify);
  ParamList.Add(@sMsg);

  result := Exec.RunProc(ParamList, ProcNo);

  FreePIFVariantList(ParamList);
end;

This solution was wrong, I'm got an error at line "result := Exec.RunProc(ParamList, ProcNo);".

"Project mcserv.exe raised exception class $C0000005 with message 'access violation at 0x00a56823: read of address 0x0000000d'.".

How I do wrong?


Solution

  • You need to create PPSVariant for string parameters :

    Param := CreateHeapVariant(fExec.FindType2(btString));
    PPSVariantAString(Param).Data := AnsiString('test value');
    

    Another way is to work with Exec.RunProcPVar() method. You just have to define an array of variant with your parameters :

    var
      vparams : array of Variant;
    begin
      Compiler := TPSPascalCompiler.Create;
      Compiler.Compile(Script);
      Compiler.GetOutput(Data);
      Compiler.Free;
    
      Exec.LoadData(Data);
    
      ProcNo := Exec.GetProc('OnBroadcastMessage');
    
      SetLength(vparams, 7);
      vparams[0] := iCID;
      vparams[1] := iUIN;
      vparams[2] := sUsersList;
      vparams[3] := dtActualTo;
      vparams[4] := bMustRead;
      vparams[5] := bReadNotify;
      vparams[6] := sMsg;
    
      Result := Exec.RunProcPVar(vparams, procno);
    
    end;