高見知英のかいはつにっし(β)

高見知英のアプリケーション開発日誌 のほか、地域活動などの活動報告ブログ。

おっ

 昨日行き詰まっていた引数の受け渡し。
さっき見つけたページで解決しました。
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=13421

 BorlandのDeveloperNetworkって、結構いろんなコードが集まってますね、
一応英語、読めないことはないんだし、今度からは参考にしなきゃ…。

 というわけで、名前で関数を呼び出すときは、呼び出す関数の第一引数に、かならずそのオブジェクトの参照(TObject)を付け加えておかないとダメなんですって。

TTMemoAPIFunc = function(obj : TObject;Argument: String): String;

というふうに。
たしか以前、「クラスメンバのメソッドには、Self: TObjectという引数が渡されている」というようなことをどこかで聞きましたが、こんなところで使うことになるとは…。
 で、これさえできていれば、引数をいくら使おうが、戻り値を返そうが、平気です。たぶんvarパラメータなんかも問題ないでしょう。
あ、そのかわりクラスメソッドであっても、クラスをインスタンス化しないと使えなくなります。
クラスはTObject型引数に入れられませんので。


 さらにもうひとつ、Socket.Dataって、PCharを渡しちゃダメだけど、オブジェクトを渡せば良かったんですね。
ClientConnectイベントで、

Socket.Data := TStringStream.Create('');

などしてあげれば、この中身はちゃんと保持してくれます。

結果、こうなりました。 

  TStringStream(Socket.Data).WriteString(Socket.ReceiveText);
  if not AnsiEndsStr(#13#10, TStringStream(Socket.Data).DataString) then exit;
  try
    api := TTMemoAPI.Create;
    try
      while AnsiContainsStr(line, #13#10) do begin
        opr := PickToken(line, #13#10);
        // 関数名から、アドレスを取得 PickToken ret=関数名 msg=引数
        func := TTMemoAPI.MethodAddress(PickToken(opr, ' '));
        if Assigned(func) then begin
          Socket.SendText(func(api, opr) + #13#10)
        end else
          Socket.SendText(TMemoAPIFunctionNotFound);
      end;
    finally
      api.Free;
    end;
  finally
    TStringStream(Socket.Data).Size := 0;
    TStringStream(Socket.Data).WriteString(line);
  end;

 いちいちストリームからいったん出してあげないといけないのが、ちょっと気になりますけど…。これにてとりあえず一件落着のようです。Telnetを二つ起動してやってみても、エラーにはなってないです。
 あとは、とりあえずlocalhost以外の接続は全てはじくように設計していますが…、
実際それだとちょっと難ありでしょうし、何か考えておきます。
localhost以外は、ワイルドカードでマッチしたIPアドレスの人のみ通すとかね。