質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

649閲覧

外部のexeファイルと入出力のやり取りを双方向に行うプログラム

GammaRayBurst

総合スコア11

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

2クリップ

投稿2023/02/04 08:16

実現したいこと

C++を用いて、既に用意されている外部のexeファイルと入出力のやり取りを双方向に行うプログラムを書きたいです。実現困難なら次点でRust、続いてGoを用いたいと考えています。

前提

言語はC++、OSはWindows11です。Pythonのsubprocessモジュールで所望の機能を持つプログラムを実現できたのですが、C++で実現する良い方法は無いのでしょうか?具体的な良い方法を知りたいです。プログラムの速度低下とメモリ消費は望んでいないため、WSLは使用したくないです。

考えられる解決策と試したこと

自分なりに調べた結果、実現するためには以下の方法が有力と分かりました。
(1)C++のpopenモジュールを使う
外部プログラムに入力だけを行うプログラムなど片方向のやり取りならpopenを使ったプログラムが検索にヒットしますが、双方向のやり取りを実現しているプログラムは全然ヒットしませんでした。辛うじてhttps://stackoverflow.com/questions/6171552/popen-simultaneous-read-and-write
が有益そうな情報としてヒットしましたが、windows環境では使用できないモジュールを使っています。上記の理由でWSL使用はしたくありません。

(2)<windows.h>のCreateProcessモジュールを使う
公式ドキュメント読んだりしましたが、windows apiが自分にとっては難しい上に双方向のやり取りに関する情報量が少ないため実装は極めて困難です。また、上記のように片方向なら検索にヒットしますが。。。

(3)他の方が用意したモジュールを使う
boostライブラリのboost::processを利用する方法を実際にやってみましたが、自力では解決不能なエラーが多発しました。また、
https://github.com/tsaarni/cpp-subprocess
https://github.com/arun11299/cpp-subprocess
などは良さげなモジュールで、導入には成功したものの解決不能なエラーが発生しました。

(4)C++のstd::systemでPythonを呼び出し、subprocessを使う
Pythonで所望の機能を持つプログラムを実現できたことを生かすならこの方法ですが、プログラム全体で外部のexeファイルとの入出力のやり取りを何百万回といった膨大な回数行いたいため、pythonを呼び出して更にsubprocessを呼び出す時間的コストが不安です…

総括

このように、どの方法も個人的な事情で難点があります。C++で所望のプログラムを実現する方法は他にありますか?また、もし無理であれば、最終的手段としてRust、Goで良い方法があるか具体的に教えていただきたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2023/02/04 09:15

入出力元のexeの詳細(一般に公開されているもの?自作?ならその入出力動作の詳細)と 実現できているPythonコードを提示すると回答得られやすいかと思います。
GammaRayBurst

2023/02/12 09:52

ありがとうございます。確かにその部分は詳細に書くべきでした。今後の参考にさせていただきます。
guest

回答1

0

ベストアンサー

既に用意されている外部の exe ファイルというのは標準入出力を使って情報を出し入れているという前提でよろしいですね?

標準入出力というのは事前準備済みの特別なパイプだと考えて下さい。 普通なら画面とキーボードに接続されている標準入出力ですが、事前にパイプを作成したものを (CreateProcess API での) 子プロセス生成時に「このパイプを標準入出力として使え」と渡すことで接続が確立します。

そのまま使えるような双方向通信の例が公式にあります。 必要だと思われる情報は全て揃っているのでこれでわからないのであればわからない箇所を具体的に質問してください。

また、 _popen も提供されており、使い方もほぼ POSIX の popen と一緒です。 UWP アプリでは使えないことや互換性の都合から名前が下線で始まるということには注意が必要ですが API を直接に使うよりは楽だと思います。

投稿2023/02/04 09:19

編集2023/02/04 09:30
SaitoAtsushi

総合スコア5444

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

GammaRayBurst

2023/02/12 09:51

様々な手段を探っていたことにより、返信遅れたことをお詫びいたします… fork()がwindowsでは使えない以上、_popenで所望のプログラムの実現は困難だろうという結論になりました。また、RustやGoを使った方法も情報が少ないので、近い事はできたもの完全な実装はできなかったのでまた誰かに聞く必要がありそうです。 Windows APIで公式を参考に実装してみたところ、所望の動作に近いプログラムは得る事はできたもののこれも完全ではないです。これに関してはまたの機会に質問してみようかと思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問