1. 程式人生 > >PaxCompiler指令碼編譯的一些要注意的問題

PaxCompiler指令碼編譯的一些要注意的問題

使用PaxCompiler做指令碼的時候,有的時候我們需要在指令碼中引用其他的指令碼檔案,如果指令碼檔案放入程式的根目錄引用是沒有任何問題的,但是我們做指令碼的時候不可能指令碼都放到程式的根目錄,這樣引用的會找不到要引用的指令碼檔案pas,但是PaxCompiler提供了一個事件,可以在指令碼編譯的時候手工載入引用的pas具體如下:

PaxCompiler1.OnUsedUnit := DoUsedUnit;  
function TForm1.DoUsedUnit(Sender: TPaxCompiler; const UnitName: string;
  var SourceCode: string): Boolean;
var
 List:TStrings ;
begin
 if CompareText(UnitName,'PXL') = 0 then
 begin
  List:=TStringList.Create ;
  try
  List.LoadFromFile(GetMediaPath+UnitName+'.pas');
  SourceCode :=List.Text;
  Result:=True ;
  Exit ;
  finally
  List.Free ;
  end;
 end;
 Result:=False ;
end;


還有需要注意的是,如果是預編譯指令碼成二進位制檔案,儘量不要將引用檔案生成PCU檔案,預設PCU是放入程式根目錄的,如果指令碼不放入根目錄會導致異常,其實也可以使用Delphi的標準載入單元的方式 in “.\***.pas”,但是考慮跨平臺的需求,就儘量不能使用了,編譯指令碼的時候設定不生成引用檔案的PCU檔案就可以了,否則在移動平臺會發生找不到目錄的異常:

var
  PaxCompiler1: TPaxCompiler;
  PaxInterpreter1: TPaxInterpreter;
  PaxPascalLanguage1: TPaxPascalLanguage;
begin
  PaxCompiler1 := TPaxCompiler.Create(nil);
  PaxInterpreter1 := TPaxInterpreter.Create(nil);
  PaxPascalLanguage1 := TPaxPascalLanguage.Create(nil);
  try
  PaxCompiler1.Reset ;
  //PaxCompiler1.OnSavePCU:=DoSavePCU ;
  //PaxCompiler1.OnSavePCUFinished:=DoSavePCUFinished;
//  PaxCompiler1.AddModule('1', 'Pascal');
//  PaxCompiler1.AddCodeFromFile('1',GetMediaPath+'PXL.pas') ;
//  if PaxCompiler1.Compile(PaxInterpreter1, true, false) then
//  begin
//    PaxInterpreter1.SaveToFile(GetMediaPath+'PXL.PCU');
//  end;
//



  PaxCompiler1.OnUsedUnit := DoUsedUnit;
//  PaxCompiler1.OnSavePCU:=DoSavePCU ;
//  PaxCompiler1.OnSavePCUFinished:=DoSavePCUFinished;
//  PaxCompiler1.OnLoadPCU:=DoLoadPCU;
//  PaxCompiler1.OnLoadPCUFinished:=DoLoadPCUFinished;

  PaxCompiler1.RegisterLanguage(PaxPascalLanguage1);
  PaxCompiler1.AddModule('1', 'Pascal');
  PaxCompiler1.AddCodeFromFile('1', GetMediaPath+'script.pas');

  {引數二 是否儲存引用檔案的PCU,引數三 是否將PCU檔案作為執行時包}
  if PaxCompiler1.Compile(PaxInterpreter1, False, false) then
  begin
    //PaxInterpreter1.Run ;
    PaxInterpreter1.SaveToFile(GetMediaPath+'script.bin');
  end
  else
  begin
   ShowMessage(PaxCompiler1.ErrorMessage[0]) ;
  end;

  finally
  FreeAndNil(PaxCompiler1);
  FreeAndNil(PaxInterpreter1);
  FreeAndNil(PaxPascalLanguage1);
  end;
end;

為了保證執行的效率,在程式開始的時候或者直接發行編譯成二進位制的指令碼檔案會更有效率,否則的話在手機平臺下,就編譯一個空的指令碼檔案也是需要很長時間的,程式會發生明顯的卡頓,更不要說每次執行指令碼都先編譯再執行,那如果再手機平臺下,程式估計會卡的死死的,通過上面的編譯就可以生成一個二進位制的包,每次執行指令碼我們都執行那個二進位制的指令碼檔案就可以了,省略了每次編譯的過程,程式速度是非常快的,省略編譯的步奏,指令碼的執行速度和delphi自己的執行速度是差不多的,PaxCompiler自帶的例子裡面有測試,具體執行二進位制指令碼程式碼如下:

var
 PaxInterpreter1: TPaxInterpreter;
begin
 PaxInterpreter1 := TPaxInterpreter.Create(nil);
 try
  PaxInterpreter1.LoadFromFile(GetMediaPath+'script.bin');
  PaxInterpreter1.MapGlobal;
  PaxInterpreter1.Run;
 finally
 FreeAndNil(PaxInterpreter1);
 end;
end;

一般只要編譯成功,執行二進位制指令碼不會發生錯誤的,需要注意的是保證註冊到指令碼的類函式等正確.