外部プログラムを実行し、C を使用してコマンド ライン パラメータを渡すにはどうすればよいですか? オペレーティング システム API を使用する必要がある場合は、Windows、Mac、および Linux 用のソリューションを含めます。
8 に答える
それは、まさにあなたがやろうとしていることによって異なります。
- OS依存
- あなたがやろうとしていることははっきりしていません。
それにもかかわらず、私はあなたが決定するためにいくつかの情報を提供しようとします.
UNIX では、fork()
fork を呼び出した場所からプロセスのクローンを作成します。つまり、次のプロセスがある場合:
#include <unistd.h>
#include <stdio.h>
int main()
{
printf( "hi 2 u\n" );
int mypid = fork();
if( 0 == mypid )
printf( "lol child\n" );
else
printf( "lol parent\n" );
return( 0 );
}
出力は次のようになります。
こんにちは 2 u
笑 子供
笑 親
fork()
子で返される pid が 0 の場合、親で返される pid は子の pid です。「hi2u」は一度だけ印刷されることに注意してください...親によって。
execve()
およびその関数ファミリーは、ほとんどfork().
execve()
の場合、渡されたアプリケーションの名前で現在のスタックフレームを上書きするなどで使用されます。execve()
ほとんどfork()
の場合、子プロセスをフォークする場所で使用されます。親の場合は、やり続けるために必要なことは何でも行い、子の場合は新しいプロセスを実行します。execve()
また、ほとんどの場合waitpid()
-- waitpid とともに使用されます。waitpid は、子プロセスの pid を受け取り、文字通り、子プロセスが終了するまで待機し、子プロセスの終了ステータスを返します。
この情報を使用すると、非常に基本的なシェルを作成できるはずです。コマンドラインでプロセス名を受け取り、指定したプロセスを実行するもの。もちろん、シェルは入力と出力のパイピングなど、それ以上のことを行いますが、fork()
、execve()
、waitpid()
.
注: これは *nix 固有です! これは Windows では機能しません。
これが役に立ったことを願っています。
外部プログラムの出力を読み取るなど、より複雑な操作を実行する場合は、 popenシステム コールを使用した方がよい場合があります。たとえば、ディレクトリのリストにプログラムでアクセスするには (これはややばかげた例ですが、例としては役に立ちます)、次のように記述できます。
#include <stdio.h>
int main()
{
int entry = 1;
char line[200];
FILE* output = popen("/usr/bin/ls -1 /usr/man", "r");
while ( fgets(line, 199, output) )
{
printf("%5d: %s", entry++, line);
}
}
このような出力を与える
1: cat1
2: cat1b
3: cat1c
4: cat1f
5: cat1m
6: cat1s
...
#include <stdlib.h>
int main()
{
system("echo HAI");
return 0;
}
システムを使用しないように大きな警告を発したいと思います。ライブラリを作成するときは、システムを 100% 使用しないでください。Unix と呼ばれるおもちゃのオペレーティング システムにマルチスレッドが知られていない 30 年前に設計されました。また、今日ほとんどすべてのプログラムがマルチスレッド化されている場合でも、まだ使用できません。
popenを使用するか、fork + execvpを実行してください。それ以外は、シグナル処理の問題、環境処理コードのクラッシュなどを見つけるのが難しくなります。選択された最も評価の高い回答が「システム"。職場でのコカインの使用を促進する方がより健康的です.
UNIX では、生成されたプロセスを生成プロセスから切り離して実行する場合は、基本的に fork する必要があると思います。たとえば、生成プロセスを終了するときに生成プロセスを終了させたくない場合などです。
これは、 Fork、System、Exec の微妙な違いをすべて説明するページです。
Win、Mac、および Linux で作業している場合は、Qt フレームワークとその QProcess オブジェクトをお勧めできますが、それが選択肢になるかどうかはわかりません。大きな利点は、Windows linux と mac で同じコードをコンパイルできることです。
QString program = "./yourspawnedprogram";
QProcess * spawnedProcess = new QProcess(parent);
spawnedProcess->start(program);
// or spawnedProcess->startDetached(program);
さらに、親プロセスから子プロセスを強制終了し、ストリームを介して子プロセスとの通信を維持することもできます。
外部コマンドの出力を確認/読み取り/解析する必要がある場合は、system() の代わりに popen() を使用することをお勧めします。
プラットフォーム依存のレシピといえば、Windows ではCreateProcessを使用し、Posix (Linux、Mac) ではfork
+を使用しますexecvp
。ただしsystem()
、基本的なニーズをカバーする必要があり、標準ライブラリの一部です。