Ticket #40978

pluginからのttset構造体へのアクセスずれる

Open Date: 2020-11-17 22:32 Last Update: 2021-12-18 00:35

Reporter:
Owner:
Type:
Status:
Closed
Component:
Priority:
5 - Medium
Severity:
5 - Medium
Resolution:
Fixed
File:
4
Vote
Score: 0
No votes
0.0% (0/0)
0.0% (0/0)

Details

普段 Teraterm 4.98 を使用してます。 AutoComPortReconnect の時、接続開始待ち時間を指定できるようにするだけのpluginを自作しました。 Teraterm 4.105 で自作pluginをビルドしましたが、 pluginの呼び出しTTXInit()で取得できる tttset 構造体の eterm_lookfeel_t EtermLookfeel; 以降は4バイトずれ、旧版の構造が引き継がれなくなっています。 r8106で追加した構造体変数の影響のようです。

Ticket History (3/24 Histories)

2020-11-17 22:32 Updated by: tomo3136
  • New Ticket "pluginからのttset構造体へのアクセスずれる" created
2020-11-21 00:12 Updated by: nmaya
Comment

対応するバージョンのソースコードを使ってプラグインをビルドしてください。

(Edited, 2020-11-21 00:12 Updated by: nmaya)
2020-11-21 18:43 Updated by: tomo3136
Comment

新旧どちらのバージョンでも同じpluginを使いたかったのですが、以下の方法にすることにしました。

tttset 構造体を参照せずに、TERATERM.INIファイルを読み込むタイミングで plugin側で"AutoComPortReconnect"を確認するようにしました。

お手数をおかけしました。ありがとうございます。

2020-11-22 16:41 Updated by: nmaya
Comment

ちなみにですが、Tera Term 4.98 のソースコードでビルドしたプラグイン(tttset 構造体を参照するもの)は、4.105 で動作しますか?

私は内部に詳しくありませんが、古いソースコードでビルドしたプラグインは新しい Tera Term でも動作することが想定されているはずです。(そういう意味で「対応するバージョンの~」と書きましたが、説明が十分ではありませんでしたね。)

今回のように逆の場合は、構造体の拡張がありうるので難しいことが想定されます。(OPENFILENAME 構造体 の lStructSize などもそうですよね)

2020-11-23 17:13 Updated by: tomo3136
Comment

確認しましたので報告します。

build:v4.98

running:v4.98 ⇒〇動作する
running:v4.105 ⇒×動作しない

build:v4.105

running:v4.98 ⇒×動作しない
running:v4.105 ⇒〇動作する

前のコメントで報告した内容でも両方のバージョンのTeratermで動作を確認出来たため、目的はクリアできましたが 別の方法(ttset構造体で無理やり対応)を実装してみました。

https://osdn.net/users/tomo3136/pf/ttxreconnect/wiki/FrontPage

※アライメント等何も考慮していないのできれいなやり方ではありませんが。

当方オープンソースに上げるのは初めてのため、とりあえず作業部屋に上げてみました。至らない点がありましたらご了承願います。

2020-11-23 19:52 Updated by: tomo3136
Comment

OPENFILENAME 構造体 の lStructSize を調べてみました。

拡張時はバージョンアップにより構造体の末尾にメンバを追加していくようです。 いつも固定値を設定するため様式美としてあまり気にしていませんでした。

lStructSizeでサイズを指定することでメモリ例外を起こしにくいようにしているようです。 また、追加メンバーより前のメンバの位置が同じならば、古いAPIの呼び出しでは追加部分は無視扱いにでき、新しいAPIの呼び出しではlStructSizeが想定より小さい値となるため、エラーにするなり互換モードで動かすなりができるようにしているものと思われます。(うまいこと考えたものです)

Teratermのtttset構造体も何度か大きな変更をしているようですが、基本的には構造を保持し、同じように末尾にメンバを追加しています。

ただ、TeratermのV4.105においては、結果的に tttset 構造体の途中にメンバが追加された形となり、以降の位置がずれてしまうため、単純に上記のような使い方はできず、Tera Termのバージョンごとに用意が必要かなと思っていました。

前のコメントのコードでは、tttset構造体にlStructSizeのように識別子として使えるものがない(v4.105ではRunningVersionが追加されている)ため、実行プログラムのバージョンを識別子として使用し、古ければ(ここではv4.105未満)指定位置以降のアドレスを強制的に構造体のメンバ位置を調整するマクロに変えてみた次第です。

2020-12-03 00:14 Updated by: zmatsuo
  • Milestone Update from (None) to Tera Term 4.106 (closed)
  • Resolution Update from None to Accepted
  • Owner Update from (None) to zmatsuo
Comment

ttset構造体を調整しました (r9042)。

Tera Term 4.98 向けビルドで 4.105 で使えるようになっていると思います。

試してみてください。

2020-12-11 01:34 Updated by: tomo3136
Comment

確認しましたので報告します。

plugin build:r9042

running:v4.98 ⇒〇動作する

running:v4.104 ⇒〇動作する

running:v4.105 ⇒×動作しない

修正内容通りv4.105 以外でプラグインを動作させることができました。

また、簡易的にTTSet構造体がずれているか確認するプラグインを作って確認しました。

https://osdn.net/users/tomo3136/pf/TTXEstimateMismatch/scm/tree/master/

2020-12-21 01:53 Updated by: zmatsuo
Comment

もう少し手直しして 4-stable に修正をマージしました。

r9112 です。確認いただけないでしょうか。

Tera Term 5 では文字列をUnicodeにすることになると思いますし 長いパス名に対応したいので構造体がずれることは確定的です。

プラグインが情報を得るときに構造体を参照するのではない 別の方法がのぞましいなと思っていますが手が回っていません。

2020-12-24 07:12 Updated by: tomo3136
Comment

確認しましたので報告します。

plugin build:4-stable r9112

running:v4.98 ⇒〇動作する

running:v4.104 ⇒〇動作する

running:v4.105 ⇒×動作しない

結果は同じことを確認しました。修正内容通りv4.105 以外でプラグインを動作させることができました。

ビルド環境は、Windows10 64-bit, Visual Studio 2019, SDK 10(cmake時) および 8.1(sln使用時), のみ。 r9112 ソースコードからはインクルードファイルのみ使用してビルド (ttpcmn とかは未使用)

実行環境は、Windows10 のみ。

2020-12-24 07:54 Updated by: tomo3136
Comment

Tear Term 5 では構造体がずれますか、、

ネットを探しても、プラグインはここ以外で見つけることができなかったので メジャーバージョンアップなら、影響出ても仕方ないかなと思います。 8つほどプラグインを作りましたが、私的には必要なら移植するだけです。(同等のI/Fの提供ならば、作業するしないだけなので)

私の主要用途は UART 通信のため、割り切って使っています。 (作ったプラグインのいくつかは、パス名を扱いますが割り切って日本語禁止にしている)

2020-12-28 22:51 Updated by: zmatsuo
Comment

確認ありがとうございます。

つぎのリリースに反映されます。

# Tera Term の内部状態を取得するAPIを追加したらどうかなぁ…

2020-12-28 22:52 Updated by: zmatsuo
  • Status Update from Open to Closed
2020-12-28 22:58 Updated by: zmatsuo
  • Resolution Update from Accepted to Fixed
2020-12-29 06:19 Updated by: tomo3136
Comment

参考までに私が使用している構造体メンバーは以下でした。

tttset 構造体読み込みのみ

HomeDir, LogFN, MacroFN, HostName, Title, PortType, TCPPort, ComPort, UILanguageFile, AutoComPortReconnect

tttset 構造体読み込み・書き込み

SetupFName, KeyCnfFN

TComVar 構造体読み込みのみ

HWin

TKeyMap, TGetHNRec 構造体

未使用

反映、ありがとうございます。

2021-02-27 01:08 Updated by: zmatsuo
Comment

例えば、こんなAPI(名前は仮です)を作って

BOOL GetVar(TTInst *ttinst, const char *key, void *ptr, size_t size);
BOOL SetVar(TTInst *ttinst, const char *key, void *ptr, size_t size);

# ttinstは、現在使用中のTera Termのハンドル的な何かです。

char *homedir;
GetVar(ttinst, "HomeDir", &homedir, sizeof(homedir));
SetVar(ttinst, "HomeDir", &homedir, sizeof(homedir));

とやると、変数の値が取得/設定できるというのはどうでしょうか?

内部データ(構造体)をプラグインから全部見れる必要はないはずなので こんな感じで良いのではないかな…。

フォルダやファイル名の長さは char の MAX_PATH文字(byte) で確保してありますが、 wchar_t にすると2倍の領域が必要になります。 32768文字のパス長に対応したいので、 動的に確保するほうが妥当だろうなと思っています。

2021-02-28 11:23 Updated by: tomo3136
Comment

TTXSetupHooks や TTXUIHooks で使う分には、広範囲に書換作業が発生するものの API 呼び出しによる動作への影響が少ないと思います。

ただし、 TTXSockHooks や TTXFileHooks で通信のたびに API 呼び出しを行う場合は、ボトルネックとなる可能性があります。

通信処理は、必要なことを最小限のコストで処理したほうが良いと考えます。

(今まで、ポインタ2回アクセスで済んでいたのが、加えて関数呼び出し、keyによる対象の検索、データのコピーが常に発生します。)

最近のPC性能からしたら影響するものではありませんが、古い環境での動作を考慮するなら影響を懸念されます。

値をプラグイン側で事前にキャッシュしておく手もありますが、本体側で変更イベントが発生した場合、通知する仕組みも欲しくなります。

ですが、通信のたびにパス文字列へのアクセスするなら、もっとコストのかかることをほかに行っていると考えられるため、この限りではないと思います。

例えば、

作ったプラグインの中には、受信文字列からパターン一致を検出したら、ログファイルに検出時刻と内容を書き出す機能があります。
書き出し時は、さらにコストのかかるログ出力フォルダへのファイルのオープン、書き出し、クローズに行っています。
(不都合は生じていないので最適化はしていませんが。。。)

そのため、

パス文字列だけ新設した API 呼び出しに移行してはどうでしょうか。


私もフォルダやファイル名は、動的に確保するほうが妥当だと思います。

(Edited, 2021-02-28 11:50 Updated by: tomo3136)
2021-12-08 00:42 Updated by: zmatsuo
Comment

お返事をしようと思いつつ時間が過ぎてしまいました。

もしよければ、trunk(Tera Term5)で プライグインがうまく使えるか見ていただけないでしょうか?

https://osdn.net/projects/ttssh2/lists/archive/dev/2021-December/000133.html

もし cmake をお使いでしたら、 TTXAdditional/ フォルダにファイルを置くと自動でビルドツリーに組み込まれる 仕組みを仕込みました。

質問などありましたら、chatやdirect,MLでメールで連絡いただければと思います。

https://ja.osdn.net/projects/ttssh2/wiki/chat

よろしくお願いします。

2021-12-14 06:48 Updated by: tomo3136
Comment

連絡ありがとうございます。

プラグインを確認しました。(ttssh2-trunk-r9584, vs2019ビルド, cmake 3.19.6, 動作環境: windows10)

おおむね動作しています。ただ、通信が関係する機能は、いま手元にある環境では確認は難しく、そのうち確認してみようと思います。

TeraTerm5 への移植・確認のメモを添付します。

TTXAdditional は、cmakeを使ってプラグインを作っているのでビルドは楽できますね。

添付の Teraterm5対応2 のようにサンプルにインストールのサンプルもあるとよいかと思います。

元々わかっていたことですが、コード的には文字列を char のままにすべきか wchar_t にすべきかの判断が移植のネックですね。

ただ、移植自体は機械的な作業なので方針を決めて一気にやってしまえばそれほど苦ではないかと。

それよりも自分的には設定ファイル(TERATERM.INI等)のパスは決め打ちにしていたので配置場所が変わったことで TeraTerm4, TeraTerm5 両方でビルドできるか心配でした。

若干問題があるものの対応できないレベルではないのでほっとしてます。

TearTerm5対応はするとして、今のところの課題は、

  • パス名は、まだ、MAX_PATH の制限下ですが大半は動的に確保するようにしたが、 MAX_PATH を超える文字列をどうやってテストするか
  • プラグインのUIの言語対応はどうしようか(プラグイン内で日本語英語を判別しているけどTeraTerm本体のLNGファイルに融合したいな)

といったところです。

(Edited, 2021-12-14 07:11 Updated by: tomo3136)
2021-12-18 00:35 Updated by: zmatsuo
Comment

試していただきありがとうございます。

コンパイル時に -DTERATERM_VER=5000 のようなオプションを付ける または、ヘッダに #define TERATERM_VER 5000 などが 入っていれば、プラグインは両対応できそうですね。

(または、プラグインバージョンとか作ったほうが良い?)

クローズしてしまったチケットで かろうじて連絡を取っている状態となっています。 もしよければML(かdiscord)に参加いただければ もっとスムーズにお話しできると思いますがいかがでしょうか?

ご一考いただければ・・。

Attachment File List

Edit

You are not logged in. I you are not logged in, your comment will be treated as an anonymous post. » Login