2

好吧,所以我有一个需要 IPC 的应用程序...我认为命名管道是可行的方法,因为它们非常易于使用。

无论如何,我有一个关于如何使用命名管道处理动态内存的问题。

假设我有这样的课程:

class MyTestClass {
public:
    MyTestClass() { _data = new int(4); }

    int GetData() { return *_data; }
    int GetData2() { return _data2; }

private:
    int* _data;
    int _data2;
};

现在,当我创建一个充满MyTestClass对象的缓冲区然后通过管道发送它们时,我显然会在目标进程中丢失 _data 并获得垃圾。我应该使用一些策略吗?我可以在简单的情况下使用值类型,但对于许多复杂的类,我需要使用某种动态内存并且我喜欢指针。

或者,我应该只考虑使用共享内存吗?谢谢

4

2 回答 2

3

命名管道和共享内存都有类似的问题:您需要将结构的内容序列化到发送端,并从接收端反序列化结构。

无论您使用的是命名管道还是共享内存,序列化过程本质上是相同的。对于嵌入式指针(如 _data 和 _data2),您需要以一致的方式序列化指针的内容。

您可以使用许多序列化策略,具体取决于您的结构在内存中的布局方式以及 IPC 的效率。或者您可以使用 DCE RPC 并让 RPC 编组代码为您处理复杂性。

于 2009-09-08T02:40:34.223 回答
1

要通过命名管道发送数据,您必须在发送端序列化(或编组)数据,并在接收端对其进行反序列化(或解组)。

这听起来很可疑,好像您只是在数据结构中写入字节的副本。这一点都不好。您没有复制分配的数据(它没有存储在数据结构的第一个和最后一个字节之间,而是完全存储在其他地方)并且您正在将指针(_data)从一台机器(或进程)复制到另一台机器,并且本地进程中的内存地址在其他进程中没有保证的意义。

为自己定义一个有线协议(如果不相关,请查看 ASN.1 - 不,再想一想,不要那么极端),它定义了通过网络传输的数据布局。然后实现发送器和接收器(或序列化器和反序列化器)功能。或者找到已经这样做的其他人的代码。

还要记住处理字节序 - 您必须定义字节通过命名管道发送的序列。

例如,您可以定义发送的消息由网络字节顺序的 4 字节无符号整数组成,定义后面有多少个结构,并且每个结构可以是数组的 4 个有符号 4 字节整数的序列,后跟一个有符号的整数4 字节整数_data2(也以网络字节顺序发送)。

请注意,选择命名管道作为 IPC 机制在很大程度上无关紧要。除非您使用共享内存(固有地在同一台机器上),否则必须处理字节序,即使使用共享内存,您也需要处理序列化。

于 2009-09-08T02:46:10.000 回答