名前付きパイプ


(注意)名前付きパイプはWindows NT以上(windows95,98,98SE,Meは不可)で使用できます。

「名前付きパイプ」は2つのプロセスの間で、プロセス間通信を行うときに使用します。名前付きパイプはネットワークで接続されたリモートコンピュータで実行されているプロセスとの間でも利用できます。ちなみに「名前なしパイプ」というのもありますが、こちらは親子プロセス間での通信に使用し、リモートコンピュータでは使用できません。

名前付きパイプは、「Delphi4 パワーガイド」でも説明がありますのでお持ちの方は参照してください。ここでは、「名前付きパイプ」が簡単に使えるクラスの例を示します。このクラスのコンストラクタは同じコンピュータ上で動作するプロセスのサーバー側のものです。クライアント側は、CreateNamedPipe関数でなくCreateFile関数を使用します。

(例)
 hPipe := CreateFile('\\.\pipe\pipe1', GENERIC_READ or GENERIC_WRITE, FILE_SHARED_READ or FILE_SHARED_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

 

{ ***********************************************************************

   名前つきパイプクラス

 *********************************************************************** }
unit clsNamedPipe;

interface

uses
	Windows, Classes, SysUtils;

const
	OutBufferSize = 1024;
    InBufferSize  = 1024;
    Timeout = 5000;

type
	TNamedPipe = class(TObject)
    private
    	FHandle: LongWord;  // パイプハンドル

	public
    	constructor Create(sName: string);
        destructor Destroy; override;

        function Read(var s: string): Integer;     // パイプから読む
        function Write(s: string): Boolean;   	// パイプに書く
    end;

implementation

{ コンストラクタ }
constructor TNamedPipe.Create(sName: string);
begin
	inherited Create;
    FHandle := CreateNamedPipe(PChar('\\.\pipe\' + sName), PIPE_ACCESS_DUPLEX, 0, PIPE_UNLIMITED_INSTANCES,
    	OutBufferSize, InBufferSize, Timeout, nil);
end;

{ デストラクタ }
destructor TNamedPipe.Destroy;
begin
    CloseHandle(FHandle);
end;

{ パイプから読む }
function TNamedPipe.Read(var s: string): Integer;
var
	buffer: array[0..InBufferSize-1] of Char;
    nBytesRead: LongWord;
begin
    if FHandle = INVALID_HANDLE_VALUE then
    begin
        Result := -1;
        Exit;
    end;

    ZeroMemory(@buffer[0], InBufferSize);
    if ReadFile(FHandle, buffer, InBufferSize, nBytesRead, nil) = LongBool(false) then
    begin
        Result := -2;
        Exit;
    end;

    Result := nBytesRead;
    s := StrPas(buffer);
end;

{ パイプに書く }
function TNamedPipe.Write(s: string): Boolean;
var
	buffer: array[0..OutBufferSize-1] of Char;
    nBytesWrite: LongWord;
begin
    if FHandle = INVALID_HANDLE_VALUE then
    begin
    	Result := false;  // NG
        Exit;
    end;
	StrPCopy(buffer, s);
	if WriteFile(FHandle, buffer, OutBufferSize, nBytesWrite, nil) = LongBool(false) then
    begin
    	Result := false;  // NG
        Exit;
    end;

    Result := true;  // OK
end;

end.