|
こんにちは。秀丸愛用者の「でるもんた・いいじま」です。
4番会議室のほうがよさそうですが、とりあえずこのまま。
> さて、複数のマクロの実行インスタンスで同じ数値配列や文字列値を
> 共有する方法がわかりません。
>
> やりたいこととしては、1番目の秀丸エディタでファイルを開いた直後などの
> 自動起動マクロで数値配列や複数の文字列などの大量の(数MB程度か)値を
> 動的に生成し、2番目以降の秀丸エディタの自動起動マクロから
> この値を読み取って利用することです。
課題が色々とありそうです。
以下、fzok4234さんには既知の内容も多々あると思いますが、一通り丁寧に整理して
みます。
☆ ☆ ☆
1) そもそも秀丸マクロには、数値配列(に限らず文字配列もですが)を外部モジ
ュールに丸ごと渡す方法が用意されていません。
仮に配列の先頭位置へのポインタを取得できたとしても、多次元配列が絡むと一筋縄
ではいかなくなります。(CとFortranの間ですら2次元配列は言語仕様が違いますの
で…。)
強引に文字列変数の中にバイナリデータを詰め込もうとしても、'\0' の扱いとか、
中身がテキストデータという前提での秀丸の内部処理(たとえば\rおよび\nの内部処
理とか、UTF-16でエンコードするならサロゲートペアの結合・分離処理とか)が邪魔
になります。
なので、DLLを書くにせよファイルに記録するにせよ、数値配列は何らかの形で文字
列に変換して保存する必要があります。
数値から文字列にするには sprintf("%d;", #data[#i][#j]) をループで回すのが順
当だと思います。
逆にその文字列を読んで数値に戻すには、1行単位で読み込んでから split( s1, s2,
s3 ) 関数で文字列の配列に保存して、そのあと適宜 val() で数値に戻します。
#sprintfで書き出す時には、何も考えずに最後の要素の後にもセミコロンを
#置いちゃって大丈夫です。それを読み込んでsplitすると、最後のセミコロンの
#後ろの部分が空文字列として切り出されますが、秀丸の文字列変数にはnullや
#undefinedの類の特殊なものは存在しないので、単純にその要素にアクセス
#せずに無視しておくだけで大丈夫なはずです。
#
#それともちろん、元から文字列になっているデータを結合する場合は
#セミコロンではなく\x01とか\x7Fとかが無難だと思います。
☆ ☆ ☆
2) 仮にメモリ上に保存する場合、すべての秀丸で関連の処理が終わったときにその
メモリを解放しなければなりません。もし放置しておくと1回数MBの繰り返しが積も
り積もってOSの再起動を要します。マクロが強制終了されたり、あるいは常駐秀丸な
りタスクマネージャーなりから日歩丸ごと落とされたりする可能性があるので、どこ
に書くのかの選択肢があまりありません。
もちろん、逆に処理完了を確信する前に解放するのは論外です。OSを巻き添えにして
落ちる可能性があります。
なので、最初のデータ生成マクロが GlobalAlloc() でメモリを確保してそのハンド
ルを共有変数に保管する、という方法は危険だと思います。
☆ ☆ ☆
結局、私が思いつくのは下の3つくらいです。
●今回のデータ管理(と、必要に応じてそれ以外の各種バックエンド処理も)を行う
ためのEXEファイルをひとつ自作して、そのプロセスのメモリ空間にデータを送り込
む。こうすれば、そのプロセスを落とすだけでメモリは自動的にOSが解放してくれま
す。
#ただしこの場合、そのプロセスとの間のインターフェイス設計が難物です。
#DDEは今では非推奨になっていますし、DLLか何かで強引に SendMessage() を
#使おうにも、別プロセスから受け取った生ポインタにはアクセスできません。
●レジストリに書き込む。書き込むためのデータ生成は sprintf("%08X", #data[#i]
[#j]) で行います。読む際は16進文字列を8バイト単位に切り出して val("0x"+$a)
です。
#この単純なコードの場合、レジストリ上の数値データはビッグエンディアンで
#保存されるので、バイナリのコードからも該当部分にアクセスする場合は
#htonl()、ntohl() をうまく使ってください。
●諦めて %TEMP% フォルダにファイルを作る。そもそも数MB程度なら丸ごとディスク
キャッシュ上に乗るはずですし、最大のメリットとして「不具合が起きても目視で簡
単にデバッグできる」という点もあります。
ちなみにレジストリや一時ファイルの場合、データの生成日時や利用日時など、必要
最低限のデータだけを共有変数に保管するのがいいと思います。その共有変数が未定
義だったり、あるいは日時があまりに古かったりする場合には再度データを生成した
り、あるいは古いデータを単純に消去したりします。
☆ ☆ ☆
以上となります。他にも何かありませんかね…。
|
|