2008-08-19 3 views
25

どのように外部プログラムを実行し、Cを使用してコマンドラインパラメータを渡しますか?オペレーティングシステムAPIを使用する必要がある場合は、Windows、Mac、Linux用のソリューションを組み込みます。Cで別のプロセスを生成するにはどうすればよいですか?

+2

私はあなたの質問を書き直す必要があると思います - 外部プロセスを開くことは*別のプロセスを産んでいるのとまったく同じではありません...違いがあります。 –

答えて

10
#include <stdlib.h> 

int main() 
{ 
    system("echo HAI"); 

    return 0; 
} 
+6

システムを使用しないでください。それはあなたとあなたの迷惑にあなたを噛まないように、マルチスレッドの安全性から遠いです。例えばシグナル処理の誤りは、最も厄介な問題のいくつかであり、「システム」はそれに満ちています。 – Lothar

4

が、私はあなたが基本的にあなたが生成されたプロセスがデタッチ実行したい場合は、それをフォークする必要があると思うstdlib.hで定義されたシステム機能ですあなたの産卵からあなたが産卵プロセスを終了させたくない場合など。

Here is aこのページでは、Fork、System、Execのすべての微妙な違いについて説明しています。

あなたがWin、Mac、Linuxで作業している場合は、Qt Framework and its QProcess objectをお勧めしますが、それがあなたのオプションかどうかわかりません。大きな利点は、WindowsのLinuxおよびMac上で同じコードをコンパイルすることができるということです。

QString program = "./yourspawnedprogram"; 
QProcess * spawnedProcess = new QProcess(parent); 
spawnedProcess->start(program); 
// or spawnedProcess->startDetached(program); 

と余分のために、あなたも、母親のプロセスから子プロセスをkill し、それとの通信に保つことができますストリームを通して。

14

外部プログラムの出力を読み込むなど、より複雑な操作を実行する場合は、popenシステムコールを使用する方がよい場合があります。この

1: cat1 
2: cat1b 
3: cat1c 
4: cat1f 
5: cat1m 
6: cat1s 
... 
のような出力を与えること

#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); 
    } 
} 

:たとえば、プログラムで(これは多少愚かな例ですが、例として有用)ディレクトリ一覧にアクセスするには、このような何かを書くことができます

15

それはだとしてそれは本当に、まさに、あなたが何をしようとしてによって異なります

  1. OS依存
  2. あなたは何をしようとしているのかはっきりしていません。

しかし、私はあなたに決定するための情報を提供しようとします。
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); 
} 

のようになります。出力は、次のとおりです。

HIを2 U
笑子供
笑親

fork()子に返されたpidが0の場合、 d親に返されたpidは子供のpidです。 「hi2u」は1回だけ印刷されます...

execve()とそのファミリの機能は、ほとんどの場合、fork().execve()などで使用され、現在のスタックフレームを渡すアプリケーションの名前で上書きします。 execve()はほとんどの場合、子プロセスをフォークする場合にはfork()と一緒に使用されます。あなたが親であれば、あなたが何をしている必要がありますか、あなたが子供であれば新しいプロセスを実行します。 execve()もほとんど常にwaitpid()と一緒に使用されます。 - waitpidは子プロセスのPIDを取ります。ちょうど文字通りは、子プロセスが終了して子プロセスの終了ステータスを返すまで待ち​​ます。

この情報を使用すると、非常に基本的なシェルを作成できるはずです。 1つはプロセス名をコマンドラインで受け取り、それを伝えるプロセスを実行するものです。もちろん、入力と出力の配管のようにシェルはそれ以上の機能を果たしますが、fork()execve()waitpid()を使って基本を達成できるはずです。

注:これは* nix固有です!これはWindowsでは動作しません。

これは助けました。

1

外部コマンドの出力を確認/読み込み/解析する必要がある場合は、system()の代わりにpopen()を使用することをお勧めします。

1

プラットフォーム依存のレシピについては、WindowsではCreateProcess、Posix(Linux、Mac)では + execvpを使用してください。しかし、system()は、あなたの基本的なニーズをカバーし、標準ライブラリの一部です。

5

ライブラリを書くときにシステムを使用しないように、システムを使用しないことを100%は警告します。 Unixと呼ばれる玩具オペレーティングシステムでは、マルチスレッドが未知の30年前に設計されました。また、今日ほとんどすべてのプログラムがマルチスレッド化されているにもかかわらず、まだ使用できません。

popenを使うか、fork + execvpを実行してください。それ以外は、シグナル処理や環境処理コードのクラッシュなどの問題を見つけるのが難しいでしょう。選択された最も評価の高い回答が、 "システム"の使用。職場でのコカインの使用を促進する方がより健康です。

関連する問題