Re: [问题] 两个程式呼叫回传问题

楼主: dirkc (3781615)   2015-05-03 13:16:28
如同版友已经有提到的,程序间通讯 (IPC) 有许多不同的方法。
考量到你提说原本用的是 system() 加上读写档案的作法,
我会建议如果改写的话,最简单的作法就是使用 POSIX 规格所提供的
popen()/pclose() 来实作,也就是 unnamed pipe 的方式。
Windows 有提供 _popen() 和 _pclose(),等同于 *nix 下的 popen()/pclose() 函数
举例,如果写一支程式要呼叫 dir,并且把执行结果存入 std::string 里面,
可以如下这样做:
#include <string> // std::string
#include <iostream> // std::cout
#include <stdio.h> // FILE, feof, fgets, _popen/_pclose
using std::string;
using std::cout;
string exec(char* cmd) {
FILE* pipe = _popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[128];
string result = "";
while(!feof(pipe)) {
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
_pclose(pipe);
return result;
}
int main() {
cout << exec("dir") << '\n';
}
你只需要把 dir 换成你的程式 B,然后再去解析 exec("B") 回传的字串结果即可。
_popen() 的原理是开启一个单向的 pipe,透过产生一个新的程序 (fork()) 透过
shell (命令列模式) 去执行所指定的程式 (上面范例中的 char* cmd),并等待程序
执行完毕。流程上类似你直接呼叫 system() 的效果,因为 system() 也是会等待程序
执行完毕。
值得留意的是,_popen() 是开启程式输出到 STDOUT 的资料,也就是说一般情况下
用 printf() 或 std::cout 输出的装置。如果你的程式 B 是写到别的装置,例如
档案、网络、或者其他 Windows 下的输出装置,_popen() 是读不到的。
如果你输出到档案的资料不只是字串这么单纯的话,你也可以把读取的机制和储存的
资料结构替换一下,例如换成 fread() 并且将结果存在 std::vector 里面。
举例:
#include <vector> // for std::vector
using std::vector;
typedef unsigned char BYTE; // 自己定义你要的字节型别
int exec2(char* cmd, vector<BYTE> &v) {
FILE* pipe = _popen(cmd, "r");
if (!pipe) return 0; // ERROR
BYTE buffer[128];
size_t n;
while(!feof(pipe)) {
n = fread(buffer, sizeof(BYTE), 128, pipe);
if(n > 0) v.insert(v.end(), buffer, buffer+n);
}
_pclose(pipe);
return 1; // SUCCESS
}
呼叫的地方:
#include <algorithm> // for std::copy
#include <iterator> // for std::ostream_iterator
using std::copy;
using std::ostream_iterator;
int main() {
vector<BYTE> r;
exec2("dir", r);
// 这里之后可以定义你处理 r 的逻辑
// 底下只是透过 std::copy 简单将其印出在画面上
copy(r.begin(), r.end(), ostream_iterator<char>(cout, ""));
}
以上应该是就你描述的情况,改写程式最短又最简单的方式了吧,我想。
※ 引述《janice001 (真理)》之铭言:
: 开发平台(Platform): (Ex: VC++, GCC, Linux, ...)
: Windows VC++
: 额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
: Nope
: 问题(Question):
: 现在我拥有两支程式 A 与 B
: A 在程式码中会使用 System() 的方式使用 B
: 目前是让 B 使用写档的方式,A再去读取B执行的结果
: 有没有撇除掉IO 硬盘的方式回传执行结果??
: 预期的正确结果(Expected Output):
: 可以回传B程式执行结果
: 错误结果(Wrong Output):
: 目前只能使用 写档方式沟通
: 补充说明(Supplement):
: 先谢谢各位 Orz
作者: LiloHuang (十年一刻)   2015-05-03 15:52:00
推认真文! popen 听起来满适合原po的 :)
作者: janice001 (真理)   2015-05-04 17:17:00
太强惹~~~~

Links booklink

Contact Us: admin [ a t ] ucptt.com