• ベストアンサー

パイプ

C++からはじめたので、パイプについてよくわかりません。 DOSで dir | more とか、UNIXで ls | more とかやると、前のコマンドの標準出力を、後ろのコマンドの標準入力に渡すというのは、わかるんですが、これはDOS上、UNIX上でのことですよね。 プログラムToプログラムで、パイプを使うには、どうしたらよいのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.4

Windowsのパイプって名前つきパイプですよね。 多少“うろ覚え”が入ってますが、参考になれば…。 まず、「名前つきパイプはNT系のみのサポート」という前提があります。 9x系では使えませんので御注意下さい。 また、名前つきパイプを実現するのはAPI呼び出しの組み合わせです。 VBからでも、C++からでも、その組み合わせ(片方がVBで他方がC++)でも可能です。 Windowsの名前つきパイプはUnixのそれとは異なり、サーバーとクライアントという位置付けで構成されます。 サーバーはCreateNamedPipeで名前つきパイプを作成します。 作成された名前つきパイプに対するアクセスは(指定によって)サーバー→クライアント、サーバー←クライアント、サーバー←→クライアントのいずれかのアクセスが可能となります。 名前つきパイプはサーバー/クライアント双方でCreateFileすれば通常ファイルと同様にReadFile、WriteFileが可能です。 概念的には「サーバーが用意した“名前つきパイプオブジェクト”を仮想ファイルとしてI/Oし通信を実現する」という感じです。 MSDNライブラリでpipe、named pipe、CreateNamedPipe、CreateFileを調べてみてください。

haporun
質問者

お礼

\\.\pipe\pipename というファイルを出力側が用意し、受け取り側がそのファイルを開いて読み取るということになるのでしょうか。 うーむ、でもNT系にしか対応していないんですよね。 ソケットを使うといいのでしょうか。 ソケットもよくわからないのですが・・・。 何か、普通のコマンドライン引数のように、互いのプログラムが何か固有の値を知っていなければ、情報を交換できないようなもの、でないような、アプリケーション通信手段はないでしょうか。 名前とかIPとかが必要ないような。 相互通信である必要はありません。

その他の回答 (3)

  • honiyon
  • ベストアンサー率37% (331/872)
回答No.3

こんにちは、honiyonです。  http://www.google.com/search?q=CreateFile+%83p%83C%83v&hl=ja&lr=  上記「CreateFile パイプ」での検索結果です。  ちょっと時間がないので詳しくは調べてないのですが、軽く見た感じそれの文献がヒットしているようです。  VC++で作ったAPIをVBで使用したいというのは、VC++で作った関数を VBで使いたいと解釈して宜しいですか? それでしたらパイプとはまた違った事になると思います。  VC++で作った関数をDLL化し、VBからその関数をロードする、という方が適切かと思います。   参考になれば幸いです(..

haporun
質問者

お礼

MSDNライブラリは見たのですが、パイプに対する知識があまりないので、これを見ただけではわかりませんでした。 具体的にやりたいことは、アプリケーションが渡す引数の変わりに、パイプを使いたいと思ったのです。 コマンドライン引数は文字制限があるので。 パイプ付きでアプリケーションを実行し、VB用にCommand$関数のようなものを作って・・・。

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.2

DOSのパイプはリダイレクトを拡張したもので、前段プロセスがファイルに吐き出した標準出力を後段プロセスが標準入力とします。 結果、前段プロセスの終了をまって後段プロセスが起動します。 これはシングルタスクであるDOSの宿命です。 UNIX(Linuxを含む)のパイプは名前つき、名前なしの2種類があり、shellコマンドで実行可能な|は名前なしパイプです。 UNIXはマルチタスクなので前段プロセスと後段プロセスは同時に実行され、バッファリング単位(標準入出力ではBUFSIZまたは'\n'まで)ごとにデータが流れます。 UNIXを例にとります。 (DOSでも同様なライブラリ関数が用意されますが、上記の理由で動作は全く違います。また、細かな仕様も違うので確認して下さい) <親プロセスが前段、後段プロセスを起動する場合> Shellのやっている事と同じです。 1.親プロセスでpipe(2)システムコールを呼び出してパイプを作成 2.fork(2)システムコールで前段プロセスを生成 3.前段プロセスの標準出力をclose(2) 4.前段プロセスでパイプ出力側をdup(2)して標準出力とする 5.後段プロセスをfork(2) 6.後段プロセスで標準入力をclose(2) 7.後段プロセスでパイプ入力側をdup(2)して標準入力とする 8.前段、後段プロセスをexec(2) 前段/後段プロセスに当たるプログラムでパイプを意識したプログラミングがなされている場合、標準入出力のclose(2)とdup(2)は不要です。 名前つきパイプも使えます。 <子プロセスからの出力を受け取る場合> 1.pipe(2)でパイプを生成する 2.fork(2)で子プロセスを生成する 3.子プロセスで標準出力をclose(2) 4.子プロセスでパイプの出力側をdup(2) 5.子プロセスを目的のプログラムにexec(2) この手順を単純化したライブラリ関数がpopen(3)です。 子プロセスに当たるプログラムがパイプを意識したプログラムの場合、標準出力のclose(2)とdup(2)は必要ありません。 詳しくはman(1)コマンドで各システムコールを調べてください。 ()の中の数字はマニュアルの章番号でmanコマンドの第2パラメータです。 man 2 pipe のように使ってください。 以上の説明は、4.3BSD,SystemV Rel3.1以降の全てのUNIX(Linux含む)で通用するはずです。 老婆心ながら… UNIXならプロセス間通信にパイプを使うのは推奨されません。 プロセス間通信はメッセージまたはUNIXドメインソケット()を使います。

haporun
質問者

補足

書き損じました、すみません。 目的のプラットフォームはWinなのです。 ・・・でも、Win上でもpopenはあるようですね。 Winプログラムでは正しく動作しないようですが。 popenは呼び出したプロセスからの出力を受け取るようですが、呼び出したプロセスに出力を与えるという動作はできないのでしょうか。 APIのCreateFileがパイプを作れるようですが、どのように扱えばいいのかわかりません。 このハンドルはCのpipe関数の返すものと方が違うようです。

  • honiyon
  • ベストアンサー率37% (331/872)
回答No.1

こんにちは、honiyonです。  Linuxであれば、 popenを使うとプログラム同士でファイル入出力間隔で通信が出来ます。  popenで、「ls」を開いてあげると、lsを実行した結果をもらえる、といった感じです。  

haporun
質問者

補足

Win上ではムリでしょうかね。 具体的にはC++でAPIを作って、VBに使わせるということをしたいのですが。

関連するQ&A

専門家に質問してみよう