外部ファンクション

SPEL+ プログラムは、Declare ステートメントを使って、DLL で定義されている外部ファンクションを実行することができます。この仕組みは、以前のバージョンの RC+ から存在するもので、DLL には 32 ビットネイティブでなければならないという制約があります。

Extension の開発キットでは、ブリッジ DLL を提供し、SPEL+ プログラムが、64 ビットアセンブリである Extension の内部関数を呼び出せる仕組みを用意しました。これが Extension の「外部ファンクション」拡張ポイントです。

この「外部ファンクション」の呼び出しは、以下の形式となります。

  • SPEL+ プログラムに、以下の Declare ステートメントを挿入する。

    Declare CallExternal, "C:\EpsonRC80\ExternalFunctionBridge.dll", "CallExternal",(commandLine$ As String, ByRef output$ As String) As Int32
    
    • commandLine$ は、ファンクション名と引数を空白で区切って与える、コマンド行を格納した文字列

    • output$ は、ファンクションの出力を格納する文字列変数

    • 戻り値は、ファンクション実行の結果コード

      • 0 は、正常終了(成功)
      • 非 0 は、エラー
    • (例)

      Int32 ret
      String output$
      ret = CallExternal("CubeRoot 10.0", ByRef output$)
      Print output$
      
      • Run ウィンドウに 2.154434690031884 と出力されます。

この拡張ポイントを使うには、デリゲート RCXExternalFunction を実装して、エクスポートし、かつメタデータとして、ファンクション名をエクスポートします。

[Export(typeof(RCXExternalFunction))]
[ExportMetadata("Name", "CubeRoot")]
public RCXExternalFunction CubeRoot = (command, parameters) =>
{
    if (parameters.Count == 0 || !double.TryParse(parameters[0], out var input))
    {
        return ValueTuple.Create(RCXResult.BadArgument, string.Empty);
    }

    double output = Math.Cbrt(input);

    return ValueTuple.Create(RCXResult.Success, output.ToString());
};

この拡張ポイントにより、Extension で実装可能なさまざまな関数を、SPEL+ プログラムから呼び出せるようになるでしょう。

なお、以下は、組み込みの「外部ファンクション」として、Extension をサポートしているエディションの RC+ では常に利用できます。

  1. 外部プログラム実行(終了を待って、出力の1行目を返します)
    ret = CallExternal("Execute program [arg(s)]", output$)
    
  2. 外部プログラム起動(終了を待ちません)
    ret = CallExternal("ExecuteNoWait program [arg(s)]", output$)
    
  3. CallExternal の結果コードに対応する文字列の取得
    ret = CallExternal("ErrorStr Str$(retCode)" output$)
    
    • Int32 ret
      String output$
      ret = CallExternal("ErrorStr 0", ByRef output$)
      Print output$
      
      • Run ウィンドウに Success と出力されます。

(上級者向け)

このほか、ブリッジ DLL には、外部ファンクションの動作を制御するための関数があります。(CallExternal と同様な Declare ステートメントが必要です)

  1. GetTimeout(ByRef timeout As Int32) As Int32
    • CallExternal のタイムアウト時間を取得します。単位はミリ秒で、初期値は 30,000 です。
  2. SetTimeout(timeout As Int32) As Int32
    • CallExternal のタイムアウト時間を設定します。単位はミリ秒です。