使用dwscript将记录类型作为参数发送

时间:2012-03-09 10:04:22

标签: delphi class record dwscript

请考虑此记录:

Type 
  TStudent = record
    Name:String;
    Age: Integer;
    Class:String;
  end;

我有一个 TSchool 课程,它具有以下功能:

function AddStudent(LStudent:TStudent):Boolean;

我想在dwsunit和这个函数中使用这个类( TSchool ),但我无法弄清楚如何将记录类型作为参数发送。 这是我到达了多远:

procedure TForm1.dwsUnitClassesTSchoolMethodsAddStudentEval(Info: TProgramInfo;
  ExtObject: TObject);
begin
  Info.ResultAsBoolean:=(ExtObject as TSchool).AddStudent(Info.Vars['LStudent'].Value);
end;

但这不起作用,它不断给我一些关于不兼容类型的错误。

我还在dwsunit中定义了一个记录TSchool,但这也没有用。 任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:2)

我现在没有Delphi 2010,但我确实有Delphi XE( 也应该在D2010中工作),所以这里有什么对我有用,你当然可以修改为满足您的需求:

program Project1;

{$APPTYPE CONSOLE}


uses
   SysUtils
  ,Windows
  ,dwsComp
  ,dwsCompiler
  ,dwsExprs
  ,dwsCoreExprs
  ,dwsRTTIExposer
  ,Generics.Collections
  ;

//  required
{$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}
{M+}

type
  //  student definition
  TStudent = record
    Name: string;
    Age: Integer;
    AClass: string;
  end;

  //  student list, we use generics
  TStudentList = class(TList<TStudent>);

  //  school class
  TSchool = class(TObject)
  private
    FStudentList: TStudentList;
  published
    constructor Create;
    destructor Destroy; override;
  published
    procedure AddStudent(AStudent: TStudent);
    function GetStudentCount: Integer;
    function GetStudent(Index: Integer): TStudent;
  end;

{ TSchool }

procedure TSchool.AddStudent(AStudent: TStudent);
begin
  FStudentList.Add(AStudent);
end;

constructor TSchool.Create;
begin
  FStudentList := TStudentList.Create;
end;

function TSchool.GetStudentCount: Integer;
begin
  Result := FStudentList.Count;
end;

function TSchool.GetStudent(Index: Integer): TStudent;
begin
  Result := FStudentList[ Index ];
end;

destructor TSchool.Destroy;
begin
  FStudentList.Free;
  inherited;
end;

procedure TestRecords;
var
  LScript: TDelphiWebScript;
  LUnit: TdwsUnit;
  LProg: IdwsProgram;
  LExec: IdwsProgramExecution;
begin
  LScript := TDelphiWebScript.Create(NIL);
  LUnit := TdwsUnit.Create(NIL);
  try
    LUnit.UnitName := 'MySuperDuperUnit';
    LUnit.Script := LScript;

    //  expose TStudent record to the script
    LUnit.ExposeRTTI(TypeInfo(TStudent));
    //  expose TSchool class to script
    LUnit.ExposeRTTI(TypeInfo(TSchool));
    //  compile a simple script
    LProg := LScript.Compile(
      'var LSchool := TSchool.Create;'#$D#$A +
      'var LStudent: TStudent;'#$D#$A +
      'var Index: Integer;'#$D#$A +
      'for Index := 0 to 10 do begin'#$D#$A +
        'LStudent.Name := Format(''Student #%d'', [Index]);'#$D#$A +
        'LStudent.Age := 10 + Index;'#$D#$A +
        'LStudent.AClass := ''a-4'';'#$D#$A +
        'LSchool.AddStudent( LStudent );'#$D#$A +
      'end;'#$D#$A +
      'PrintLn(Format(''There are %d students in school.'', [LSchool.GetStudentCount]));'#$D#$A +
      'LStudent := LSchool.GetStudent( 5 );'#$D#$A +
      'PrintLn(''6th student info:'');'#$D#$A +
      'PrintLn(Format(''Name: %s''#$D#$A''Age: %d''#$D#$A''AClass: %s'', [LStudent.Name, LStudent.Age, LStudent.Aclass]));'
    );

    if LProg.Msgs.HasErrors then begin
      Writeln(LProg.Msgs.AsInfo);
      Exit;
    end;

    try
      LExec := LProg.Execute;
    except
      on E: Exception do
        WriteLn(E.Message + #$D#$A + LExec.Msgs.AsInfo );
    end;
    Writeln(LExec.Result.ToString);
  finally
    LScript.Free;
  end;
end;

begin
  try
    Writeln('press enter to begin');
    Readln;
    TestRecords;;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.