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