C++ を使用して 2 つのプロセスをコーディングしました。CreateProcess
1 つは、 APIを使用してコンソール アプリによって呼び出される GUI プロセスです。GUI アプリ (子) からコンソール アプリ (親) にテキストを渡す必要があります。テキストの量は、数行から数 KB のテキストまで任意です。
それを行う最も簡単な方法は何ですか?
PS。両方のプロセスのソース コードにアクセスできます。
C++ を使用して 2 つのプロセスをコーディングしました。CreateProcess
1 つは、 APIを使用してコンソール アプリによって呼び出される GUI プロセスです。GUI アプリ (子) からコンソール アプリ (親) にテキストを渡す必要があります。テキストの量は、数行から数 KB のテキストまで任意です。
それを行う最も簡単な方法は何ですか?
PS。両方のプロセスのソース コードにアクセスできます。
コンソール アプリケーションは、メッセージを受信できるように、WinAPI ウィンドウ (非表示) を作成できます (アイデアは Delphi の AllocateHWND 関数から取られました)。
別の解決策は、名前付きパイプを使用することです。
もう 1 つの解決策は、TCP/IP 経由でローカルにデータを送信することです。
これらの文字列がデバッグ用のみの場合は、WinAPI の OutputDebugString 関数を使用し、SysInternals のDbgViewなどのプログラムでキャプチャすることを検討してください。
簡単な方法は、ウィンドウも作成する場合でも、子を実際にコンソールアプリケーションにすることです。
その場合、を使用して親に子を生成させることができ_popen
、子は出力を通常のstdout
/に書き込むことができstd::cout
ます。_popen
を返すFILE *
ので、親は通常ファイルを読み取るのとほぼ同じように子の出力を読み取ることができます(通常、Cの場合はとにかく)。
さまざまな方法を使用できますが、そのうちのいくつかは上記で説明されています。どちらが最も簡単かは、タスクによって異なります。また、IPC で広く使用されているファイルマッピング技術
を
提案することもできます。dll は、ファイルマッピングを使用して実装されます。
これにより、複数のプロセスが同じリソースを同時に共有できます。アクセスは結果的ではなくランダムです。実装の主な手順は次のとおりです。
1.プロセス A がファイルを作成します。
2.プロセス A は、名前付きシステム オブジェクトの mappedfile をファイルに作成します (mappedfile はメモリを割り当てます)。
3.プロセス A は、viewOfMapped ファイルのシステム オブジェクトを作成します (これにより、プロセス A の一部の領域を、mappedFile によって割り当てられたメイン メモリ内のページにマップできます)。
4.プロセス B は、名前付きシステム オブジェクトの mapsfile (名前は、プロセス A で使用されたものと同様の名前にする必要があります)、viewOfMapped ファイルを作成します。
5. viewOfMapped プロセスによって返されたポインタによって、同じメモリを共有できます。例:
プロセス A:
/* 1. file creation */
hFile = CreateFile(0, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
NULL);
/* 2. Create file mapping */
wchar_t lpName[] = L"fileMappingObject0";
HANDLE hfileMappingObject;
hfileMappingObject = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 1024, lpName);
/* 3. Create MappedFileViewOfFile */
void* p = (MapViewOfFile(hfileMappingObject, FILE_MAP_ALL_ACCESS, 0, 0, 0));
プロセス B:
/* 2. Create file mapping */
wchar_t lpName[] = L"fileMappingObject0";
HANDLE hfileMappingObject;
hfileMappingObject = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 1024, lpName);
/* 3. Create MappedFileViewOfFile */
void* p = (MapViewOfFile(hfileMappingObject, FILE_MAP_ALL_ACCESS, 0, 0, 0));
この方法はかなり単純で強力です。
GUI アプリケーションが本当にグラフィカルなだけである場合、標準出力ストリーム (つまり ) は実際には使用しませんstd::cout
。これは、コンソール アプリケーションへの出力に再利用できます。
まず、次を使用して匿名パイプを作成する必要がありますCreatePipe
。
HANDLE hPipeRead;
HANDLE hPipeWrite;
CreatePipe(&hPipeRead, &hPipeWrite, NULL, 0);
ここで、通常のファイル ハンドルとして使用できるハンドルが必要です。1 つは読み取り用で、もう 1 つは書き込み用です。書き込みハンドルは、作成する新しいプロセスの標準出力として設定する必要があります。
STARTUPINFO startupInfo = { 0 };
startupInfo.cb = sizeof(startupInfo);
startupInfo.dwFlags = STARTF_USESTDHANDLES;
startupInfo.hStdOutput = hPipeWrite; // Standard output of the new process
// is set to the write end of the pipe
CreateProcess(
lpApplicationName,
lpCommandLine,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&startupInfo, // Use our startup information
&processInfo);
子プロセスが親に書き込む必要があるときはいつでも、標準出力のみを使用する必要があります。
std::cout << "In child process, are you getting this parent?";
親はReadFile
、パイプの読み取り側から読み取るために使用します。
char buffer[256];
DWORD bytesRead = 0;
ReadFile(hPipeRead, buffer, sizeof(buffer), &bytesRead, NULL);
注:私はしばらく WIN32 プログラミングを行っていないため、詳細が間違っている可能性があります。しかし、うまくいけば、あなたが始めるのに十分なはずです.
もちろん、プロセス間通信 (IPC)の場合、ソケット、ファイル、共有メモリなど (ただしこれらに限定されません) を含む多くの方法があります。