ある機能を実現したいと思ったとき、すべて内部で処理するのではなく、ほかのソフトに制御を移してやってもらうという方法があります。うまく使えば、プログラミングの労力が減らせます。
[トップページ] / [CによるMS-DOSプログラミング]
system()関数は、引数として受け取った文字列をそのまま実行します。COMMAND.COMをロードするので、
system( "DIR /W" );
system( "MORE < HOGE.TXT" );
のように、MS-DOSの内部コマンドを実行したり、リダイレクトが可能です。
/* SAMPLE04.C */ #include <stdio.h> #include <stdlib.h> #include <string.h> int main( int argc, char *argv[] ) { char buf[ 256 ] = "type "; strcat( buf, argv[ 1 ] ); printf( "%sを実行します。\n", buf ); system( "PAUSE" ); system( buf ); return 0; }
A>SAMPLE04 HOGE.TXT
とすることにより、TYPE HOGE.TXTを実行するプログラムです。はっきり言ってこのプログラムは意味がないので、有効な利用法を考えてみてください。
system()関数は、何でも実行できて便利なのですが、COMMAND.COMをロードするためメモリを消費してしまいます。直接プログラムを実行したいときには、spawn()を使います。
実際には、spawnl,spawnlp,spawnv,spawnvp,spawnle,spawnlpe,spawnve,spawnvpeというように、さまざまな関数が用意されています(LSI Cの場合)。spawnに続く文字で動作が微妙に異なります。
l 引数をリスト形式で渡す
v 引数を配列で渡す
p 環境変数PATHを使って実行ファイルを探す
e 子プロセスに環境変数の配列を渡す
pは大変ありがたいので、よく使うのはspawnlpとspawnvpでしょう。
int spawnlp( int mode, char *name, char *arg0, char *arg1, ..., NULL );
int spawnvp( int mode, char *name, char *argv[] );
modeには、P_WAITと記述します。子プロセス実行中は、親プロセスは停止するという意味です。P_OVERLAYと書くと制御が戻ってこないので、あまり使い道はありません。ちなみにP_OVERLAYは、exec()という関数と同じ働きをします。
nameには、実行したいプログラム名を書きます。次の引数であるarg0やargv[ 0 ]にもプログラム名が入ることに注意してください。また、最後は必ずNULLで終わらせなければなりません。
では、2つの違いをプログラムで見てみましょう。
/* SAMPLE05.C */ #include <stdio.h> #include <stdlib.h> #include <process.h> int main( void ) { char *argv[ 3 ]; spawnlp( P_WAIT, "TREE.COM", "TREE.COM", "/A", NULL ); argv[ 0 ] = "TREE.COM"; argv[ 1 ] = "/A"; argv[ 2 ] = NULL; spawnvp( P_WAIT, "TREE.COM", argv ); return 0; }
どちらを使っても処理は同じなので、都合の良いほうを選びましょう。
このようにしてほかのソフトを実行させると、楽ができるというわけです。P_WAITとしてあるので、そのソフトが終了すれば、制御は戻ってきます。関数を呼び出すのと同じ感覚ですね。
ほかのソフトを実行中は、自分のプログラムはメモリに常駐したままなので、メモリを圧迫していることを頭に入れておかねばなりません。system()では、COMMAND.COMの分も余計に使います。ですから、少しでもメモリ消費を抑えるよう工夫しましょう(メモリモデル、コンパイル方法、配列の大きさなど)。
[トップページ] / [CによるMS-DOSプログラミング]