【问题标题】:Robust, simple (and fast) interprocess communication in C++ on WindowsWindows 上 C++ 中强大、简单(且快速)的进程间通信
【发布时间】:2013-09-22 07:10:43
【问题描述】:

我正在为两个第 3 方程序开发插件:Windows (7) 上的 C++ 中的 A 和 B,并且需要一种健壮、相对简单(且快速)的方式来在两个程序之间进行通信。

通信是一种方式:基于程序 A 中的用户交互,我希望程序 A 中的插件发送一个信号,该信号最终调用程序 B 中我的插件中的函数。

协议很简单。这是我在B的插件里面接收函数的签名:

struct XYZ { 
   double x, y, z;
}
void polyLineSelected(long id, std::vector<XYZ> & points);

您会如何建议这样做?

【问题讨论】:

  • 提升进程间?有一件事肯定是它很容易使用
  • “每笔交易”有多少数据? (例如,vector 有多大?
  • 非常小。说最多 20 分,通常只有 4 分。
  • 管道或内存映射文件似乎是合理的。
  • 那么我可能会使用命名管道...

标签: c++ ipc


【解决方案1】:

到目前为止,在 Windows 上实现单向通信的最简单方法是发送WM_COPYDATA 消息。将任意数据从一个应用程序移动到另一个应用程序需要一个COPYDATASTRUCT 参数。

对于您的具体示例,发送方的实现如下所示:

// Declare symbolic constants to identify data
enum DataType {
    DataType_Points
};
// Declare struct to hold compound data
struct IPCData {
    long id;
    XYZ pts[];
};

// Allocate buffer
const size_t bufferSize = offsetof(IPCData, pts[points.size()]);
vector<char> buffer(bufferSize);
IPCData* pData = reinterpret_cast<IPCData*>(&buffer[0]);

// Fill the buffer
pData->id = 42;
copy(points.begin(), points.end(), &pData->pts[0]);

// Prepare COPYDDATASTRUCT
COPYDATASTRUCT cds = { 0 };
cds.dwData = DataType_Points;  // Can be used by the receiver to identify data
cds.cbData = bufferSize;
cds.lpData = pData;

// Send the data
SendMessage(hWndRecv, WM_COPYDATA,
            (WPARAM)hWndSender,
            (LPARAM)(LPVOID)&cds);

【讨论】:

  • 我是这种方法的新手,只是通过一个例子仔细阅读。我的理解是否正确,调用者 (A) 使用进程 B 的名称向其发送消息,并且进程 B 像来自操作系统的任何其他事件一样接收消息?
  • @Andy 调用者需要知道接收者的HWNDUsing Data Copy 的示例代码使用目标窗口的名称来检索句柄。无论哪种方式,您的发送者都需要检索接收者的窗口句柄。在接收端,您可以像处理任何其他消息一样处理 WM_COPYDATA
  • @Zac 不,你永远不想使用PostMessage。阅读documentation“当这个消息被发送时,引用的数据不能被发送进程的另一个线程改变。”你想阻塞发送者(A)直到接收者( B) 已完成对消息的处理。
  • 对不起,我的观点被打断了。如果您使用SendMessage,您在 A 中的线程将被阻塞,直到 B 处理它。如果 B 不处理它(或需要很长时间来处理它),A 将保持死锁状态。如果您使用这种机制来回发送数据,您可以轻松地使两个程序死锁。
  • B 向 A 发送消息并等待 A 处理消息,然后再从 SendMessage 调用返回。如果 A 不处理消息,则 B 会“卡”在 SendMessage 调用中(是的,SendMessage 有一个消息泵,但是在 SendMessage 调用之后发生的任何事情都不会运行)。如果 A 做同样的事情,而 B 不处理消息,那么它们都被困在运行它们的消息循环并且永远不会完成它们开始的过程。又名:死锁。
猜你喜欢
  • 2011-01-14
  • 2011-02-10
  • 2011-06-24
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 2010-09-08
相关资源
最近更新 更多