Delphi:如何在Delphi中调用R函数(或集成R)?

时间:2014-07-25 10:49:38

标签: mysql r function delphi

有没有人有如何在Delphi中使用R函数的提示或示例?我通过My​​SQL以集成方式使用R和Delphi我从Delphi发送输入到MySQL,运行连接到MySQL的R脚本函数/函数(包RMySQL)并将输出返回给MySQL,然后使用Delphi。但是这个过程很慢,这取决于脚本R的大小。有没有人有一个例子或小费来加快这个过程?

website有一个示例,但所有链接都已关闭。下面的代码显示了如何使用present R和Delphi的一个小例子。

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Datasnap.Provider,
  Data.DB, Datasnap.DBClient;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses Unit2;

function StartRAndWait (CommandLine : string) : Boolean;
var
    Proc_info: TProcessInformation;
    Startinfo: TStartupInfo;
    ExitCode: longword;
    CreateOK : Boolean;
begin
    Result := False;

    { Initialize the structures }

    FillChar(proc_info, sizeof (TProcessInformation), #0);
    FillChar(startinfo, sizeof (TStartupInfo), #0);
    Startinfo.cb := sizeof (TStartupInfo);
    Startinfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
    Startinfo.wShowWindow := SW_HIDE;

    { Attempt to create the process. If successful wait for it to end}

    CreateOK := CreateProcess(Nil, PChar('C:\Program Files\R\R-3.0.2\bin\x64\R.exe ' + CommandLine), nil,
       nil,False, CREATE_NEW_PROCESS_GROUP+NORMAL_PRIORITY_CLASS, nil,
       nil, StartInfo, proc_info);
    if (CreateOK) then begin
       WaitForSingleObject (proc_info.hProcess, INFINITE);
       GetExitCodeProcess(proc_info.hProcess, ExitCode);
       Result := True
       end;
    CloseHandle(proc_info.hThread);
    CloseHandle(proc_info.hProcess);
    end;

procedure TForm1.Button1Click(Sender: TObject);
var
    Command: STRING;
begin

  DataModule.ClientDataSet.Open;
  DataModule.ClientDataSet.Insert;
  DataModule.ClientDataSeta.AsFloat:= strtofloat(Edit1.Text);
  DataModule.ClientDataSetb.AsFloat:= strtofloat(Edit2.Text);
  DataModule.ClientDataSet.Post;
  DataModule.ClientDataSet.ApplyUpdates(0);
  DataModule.ClientDataSet.Close;
  Screen.Cursor := crHourGlass;
  try
    Command := 'CMD  BATCH  script.R  outputconsole.txt';
    StartRAndWait(Command);
  finally
    Screen.Cursor := crDefault
  end;

  DataModule.ClientDataSet.Open;
  DataModule.ClientDataSet.Last;
  Edit3.Text:= DataModule.ClientDataSetresult.AsString;
  DataModule.ClientDataSet.Close;

end;
end.

2 个答案:

答案 0 :(得分:2)

在我看来,这根本不是真正的德尔福问题。您已经提供了Delphi代码,但这里的R代码非常重要。您的Delphi程序只是启动一个新的R进程,并等待它终止。是的,启动新流程会产生一些开销,但我的猜测是大部分时间花在执行R代码上。

所以,如果你想加快整个计算的速度,首先要做的是加快计算时间最长的部分。这似乎是在R下执行的部分。

可以在其他进程中嵌入R.这可以让您避免每次要执行R代码时等待新的R进程启动。但是,嵌入R并不是最简单的事情。有很好的R包可以很容易地在C ++中嵌入R.我在考虑Dirk Eddelbuettel's Rcpp suite,特别是Rinside。你可以使用它,或至少从中汲取灵感。但是,我强烈怀疑嵌入不会解决根本问题,这只是因为你的R代码运行时间比你想要的要长。

答案 1 :(得分:0)

我认为你可以通过" ShellExecute"并且不需要TProcessinformation和TStartupInfo。