2009-09-08 58 views
2

Hokay,所以我有一個應用程序,我需要一些IPC ...我認爲命名管道是要走的路,因爲它們很容易使用。命名管道動態內存策略?

無論如何,我有一個關於如何處理動態內存使用命名管道的問題。

說我有一類像這樣:

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

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

private: 
    int* _data; 
    int _data2; 
}; 

現在,當我創建一個完整的MyTestClass對象的緩衝,然後送他們在管,我顯然失去_data在目標進程,越來越垃圾。我應該使用這種策略嗎?我可以爲簡單情況使用值類型,但對於許多複雜類我需要使用某種動態內存,我喜歡指針。

或者,我應該只是看看使用共享內存呢?謝謝

+0

我想你應該刪除'_data2'和whatnot。它不完整(初始化),我認爲你的問題無論如何都是清楚的。 – GManNickG 2009-09-08 02:37:11

+0

由於你的構造函數分配內存,你需要一個析構函數來釋放內存,不是嗎? – 2009-09-08 02:38:57

+0

是的,我確實需要釋放它,對不起的形式抱歉...我只是想得到跨越 – Polaris878 2009-09-08 03:11:58

回答

3

命名管道和共享內存都有類似的問題:您需要將結構的內容序列化到發送端,並從接收端反序列化結構。

無論您使用的是命名管道還是共享內存,序列化過程基本相同。對於嵌入式指針(如_data和_data2),您需要以一致的方式序列化指針的內容。

您可以使用很多序列化策略,具體取決於您的結構在內存中的佈局以及IPC的效率。或者你可以使用DCE RPC,讓RPC封送處理代碼爲你處理複雜問題。

+0

感謝您的迴應...我可以使用的任何協議技巧或序列化策略我可以使用?謝謝 – Polaris878 2009-09-08 03:17:52

+0

如果您正在尋找序列化策略,那麼最常見的情況是文件存儲。你如何將你的課程寫入一個文件並在稍後閱讀?如果您將IPC頻道封裝爲「std :: streambuf」,則可能可以節省大量工作量;這樣你可以共享和重用很多代碼。 – MSalters 2009-09-08 10:47:00

+0

MSalters把話說出我的嘴巴。他的建議很明顯。 – 2009-09-09 05:24:40

1

要通過命名管道發送數據,必須對發送端的數據進行序列化(或封送),並在接收端對其進行反序列化(或解組)。

聽起來很可疑,好像你只是在數據結構中寫入字節的副本。這是沒有用的。您不復制分配的數據(它不存儲在數據結構的第一個字節和最後一個字節之間,而是存儲在其他位置),並且您正在將一個指針(_data)從一臺機器(或進程)複製到另一臺機器上,並且另一方面,本地進程中的內存地址沒有保證的意義。

定義你自己的一個有線協議(如果絕望的話,看看ASN.1 - 不要,再想一想,不要那麼絕望),它定義了通過線路傳輸數據的佈局。然後實現發送者和接收者(或者seralizer和deserializer)函數。或者找到其他人的代碼已經這樣做了。

還記得要處理endian-ness - 你必須定義哪個序列的字節通過命名管道發送。例如,您可以定義發送的消息由網絡字節順序中的一個4字節無符號整數組成,用於定義後面有多少個結構,每個結構可以是該數組後面的4個有符號4字節整數的序列由_data2的單個帶符號的4字節整數(也以網絡字節順序發送)。

請注意,命名管道作爲IPC機制的選擇在很大程度上並不重要;除非你使用共享內存(固有地在同一臺機器上),否則必須處理endian-ness,即使使用共享內存,你也需要處理序列化。

+0

謝謝...這就是我在想...我對IPC的東西有點新。現在我只是通過哈哈發送原始字節...我想看看這些IPC機制的限制是什麼。對於不在數據結構中的字節,你是100%正確的......這正是我試圖解決的問題。 – Polaris878 2009-09-08 03:17:19