昨日行き詰まっていた引数の受け渡し。
さっき見つけたページで解決しました。
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アドレスの人のみ通すとかね。